From 1669c0afbd121be45c41126ef5d09f44768e0e0a Mon Sep 17 00:00:00 2001 From: Ananyo Maiti Date: Wed, 17 Jul 2019 14:47:27 -0400 Subject: [PATCH] Add print preview support (see issue #123) Pass the `--enable-print-preview` command-line flag to enable. Currently only supported on Windows and Linux. --- BUILD.gn | 23 +- libcef/browser/browser_context.cc | 17 + libcef/browser/browser_context.h | 9 + libcef/browser/browser_host_impl.cc | 55 +- libcef/browser/browser_host_impl.h | 5 +- libcef/browser/browser_main.cc | 4 + libcef/browser/browser_platform_delegate.cc | 29 +- libcef/browser/browser_platform_delegate.h | 12 +- libcef/browser/chrome_browser_process_stub.cc | 31 +- libcef/browser/chrome_browser_process_stub.h | 4 + libcef/browser/content_browser_client.cc | 22 +- .../extensions/browser_extensions_util.cc | 8 +- .../browser_platform_delegate_native_linux.cc | 14 +- .../browser_platform_delegate_native_linux.h | 2 + .../browser_platform_delegate_native_mac.h | 2 + .../browser_platform_delegate_native_mac.mm | 13 + .../browser_platform_delegate_native_win.cc | 15 +- .../browser_platform_delegate_native_win.h | 2 + libcef/browser/native/window_delegate_view.cc | 15 +- libcef/browser/native/window_delegate_view.h | 6 +- libcef/browser/net/chrome_scheme_handler.cc | 1 + .../osr/browser_platform_delegate_osr.cc | 2 + libcef/browser/prefs/browser_prefs.cc | 14 + .../constrained_window_views_client.cc | 42 ++ .../constrained_window_views_client.h | 16 + libcef/browser/printing/print_view_manager.cc | 152 ++++- libcef/browser/printing/print_view_manager.h | 49 +- .../printing/print_view_manager_base.cc | 559 ----------------- .../printing/print_view_manager_base.h | 187 ------ .../views/browser_platform_delegate_views.cc | 32 +- .../views/browser_platform_delegate_views.h | 6 +- libcef/browser/views/browser_view_impl.cc | 10 +- libcef/browser/views/browser_view_impl.h | 7 +- libcef/browser/views/browser_view_view.cc | 5 + libcef/browser/views/browser_view_view.h | 4 + libcef/browser/web_contents_dialog_helper.cc | 72 +++ libcef/browser/web_contents_dialog_helper.h | 51 ++ libcef/common/cef_switches.cc | 3 + libcef/common/cef_switches.h | 1 + libcef/common/extensions/extensions_util.cc | 18 + libcef/common/extensions/extensions_util.h | 3 + libcef/common/main_delegate.cc | 32 + libcef/renderer/content_renderer_client.cc | 9 +- .../print_render_frame_helper_delegate.cc | 20 +- .../print_render_frame_helper_delegate.h | 4 + patch/patch.cfg | 21 +- .../print_header_footer_1478_1565.patch | 573 ------------------ patch/patches/print_preview_123.patch | 336 ++++++++++ tools/gn_args.py | 6 +- 49 files changed, 1098 insertions(+), 1425 deletions(-) create mode 100644 libcef/browser/printing/constrained_window_views_client.cc create mode 100644 libcef/browser/printing/constrained_window_views_client.h delete mode 100644 libcef/browser/printing/print_view_manager_base.cc delete mode 100644 libcef/browser/printing/print_view_manager_base.h create mode 100644 libcef/browser/web_contents_dialog_helper.cc create mode 100644 libcef/browser/web_contents_dialog_helper.h delete mode 100644 patch/patches/print_header_footer_1478_1565.patch create mode 100644 patch/patches/print_preview_123.patch diff --git a/BUILD.gn b/BUILD.gn index 4d51c2e66..038d279ae 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -138,7 +138,8 @@ if (is_win) { # Set ENABLE_PRINTING=1 ENABLE_BASIC_PRINTING=1. assert(enable_basic_printing) -assert(!enable_print_preview) +assert(enable_print_preview) +assert(!enable_service_discovery) # Enable support for Widevine CDM. assert(enable_widevine) @@ -452,12 +453,12 @@ static_library("libcef_static") { "libcef/browser/prefs/renderer_prefs.h", "libcef/browser/print_settings_impl.cc", "libcef/browser/print_settings_impl.h", + "libcef/browser/printing/constrained_window_views_client.cc", + "libcef/browser/printing/constrained_window_views_client.h", "libcef/browser/printing/printing_message_filter.cc", "libcef/browser/printing/printing_message_filter.h", "libcef/browser/printing/print_view_manager.cc", "libcef/browser/printing/print_view_manager.h", - "libcef/browser/printing/print_view_manager_base.cc", - "libcef/browser/printing/print_view_manager_base.h", "libcef/browser/process_util_impl.cc", "libcef/browser/resource_context.cc", "libcef/browser/resource_context.h", @@ -482,6 +483,8 @@ static_library("libcef_static") { "libcef/browser/trace_subscriber.cc", "libcef/browser/trace_subscriber.h", "libcef/browser/thread_util.h", + "libcef/browser/web_contents_dialog_helper.cc", + "libcef/browser/web_contents_dialog_helper.h", "libcef/browser/web_plugin_impl.cc", "libcef/browser/web_plugin_impl.h", "libcef/browser/x509_certificate_impl.cc", @@ -605,10 +608,14 @@ static_library("libcef_static") { "libcef/utility/content_utility_client.cc", "libcef/utility/content_utility_client.h", - # Part of //chrome/renderer. Not included by that target because CEF builds - # with enable_print_preview=0. - "//chrome/renderer/pepper/chrome_pdf_print_client.cc", - "//chrome/renderer/pepper/chrome_pdf_print_client.h", + "//chrome/browser/local_discovery/service_discovery_device_lister.cc", + "//chrome/browser/local_discovery/service_discovery_device_lister.h", + "//chrome/browser/local_discovery/service_discovery_client_impl.cc", + "//chrome/browser/local_discovery/service_discovery_client_impl.h", + "//chrome/browser/local_discovery/service_discovery_client.cc", + "//chrome/browser/local_discovery/service_discovery_client.h", + "//chrome/browser/local_discovery/service_discovery_shared_client.cc", + "//chrome/browser/local_discovery/service_discovery_shared_client.h", ] configs += [ @@ -1354,6 +1361,7 @@ repack("pak") { sources = [ "$root_gen_dir/chrome/browser_resources.pak", "$root_gen_dir/chrome/net_internals_resources.pak", + "$root_gen_dir/chrome/print_preview_resources.pak", "$root_gen_dir/chrome/common_resources.pak", "$root_gen_dir/components/components_resources.pak", "$root_gen_dir/cef/cef_resources.pak", @@ -1369,6 +1377,7 @@ repack("pak") { public_deps = [ "//chrome/browser:resources", "//chrome/browser/resources:net_internals_resources", + "//chrome/browser/resources:print_preview_resources", "//chrome/common:resources", "//components/resources:components_resources", ":cef_resources", diff --git a/libcef/browser/browser_context.cc b/libcef/browser/browser_context.cc index 7e129c6f8..b6ad7ca1a 100644 --- a/libcef/browser/browser_context.cc +++ b/libcef/browser/browser_context.cc @@ -27,6 +27,7 @@ #include "chrome/browser/font_family_cache.h" #include "chrome/browser/plugins/chrome_plugin_service_filter.h" #include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h" +#include "chrome/common/pref_names.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/guest_view/browser/guest_view_manager.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" @@ -740,3 +741,19 @@ network::mojom::NetworkContext* CefBrowserContext::GetNetworkContext() { DCHECK(net_service::IsEnabled()); return GetDefaultStoragePartition(this)->GetNetworkContext(); } + +DownloadPrefs* CefBrowserContext::GetDownloadPrefs() { + CEF_REQUIRE_UIT(); + if (!download_prefs_) { + download_prefs_.reset(new DownloadPrefs(this)); + } + return download_prefs_.get(); +} + +bool CefBrowserContext::IsPrintPreviewSupported() const { + CEF_REQUIRE_UIT(); + if (!extensions::PrintPreviewEnabled()) + return false; + + return !GetPrefs()->GetBoolean(prefs::kPrintPreviewDisabled); +} diff --git a/libcef/browser/browser_context.h b/libcef/browser/browser_context.h index f450f3323..23bcd82df 100644 --- a/libcef/browser/browser_context.h +++ b/libcef/browser/browser_context.h @@ -13,6 +13,7 @@ #include "base/files/file_path.h" #include "base/memory/ref_counted.h" +#include "chrome/browser/download/download_prefs.h" #include "components/proxy_config/pref_proxy_config_tracker.h" #include "components/visitedlink/browser/visitedlink_delegate.h" #include "content/public/browser/browser_context.h" @@ -257,6 +258,12 @@ class CefBrowserContext : public ChromeProfileStub, return url_request_getter_; } + // Called from DownloadPrefs::FromBrowserContext. + DownloadPrefs* GetDownloadPrefs(); + + // Returns true if this context supports print preview. + bool IsPrintPreviewSupported() const; + private: // Allow deletion via std::unique_ptr(). friend std::default_delete; @@ -292,6 +299,8 @@ class CefBrowserContext : public ChromeProfileStub, // SimpleKeyedServiceFactory. std::unique_ptr key_; + std::unique_ptr download_prefs_; + DISALLOW_COPY_AND_ASSIGN(CefBrowserContext); }; diff --git a/libcef/browser/browser_host_impl.cc b/libcef/browser/browser_host_impl.cc index 55b05999d..b3b56d113 100644 --- a/libcef/browser/browser_host_impl.cc +++ b/libcef/browser/browser_host_impl.cc @@ -43,6 +43,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/command_line.h" +#include "chrome/browser/printing/print_view_manager.h" #include "chrome/browser/spellchecker/spellcheck_factory.h" #include "chrome/browser/spellchecker/spellcheck_service.h" #include "chrome/browser/ui/prefs/prefs_tab_helper.h" @@ -769,11 +770,19 @@ void CefBrowserHostImpl::DownloadImage( void CefBrowserHostImpl::Print() { if (CEF_CURRENTLY_ON_UIT()) { - content::WebContents* actionable_contents = GetActionableWebContents(); + auto actionable_contents = GetActionableWebContents(); if (!actionable_contents) return; - printing::CefPrintViewManager::FromWebContents(actionable_contents) - ->PrintNow(actionable_contents->GetRenderViewHost()->GetMainFrame()); + + auto rfh = actionable_contents->GetMainFrame(); + + if (IsPrintPreviewSupported()) { + printing::CefPrintViewManager::FromWebContents(actionable_contents) + ->PrintPreviewNow(rfh, false); + } else { + printing::PrintViewManager::FromWebContents(actionable_contents) + ->PrintNow(rfh); + } } else { CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefBrowserHostImpl::Print, this)); } @@ -1480,6 +1489,22 @@ bool CefBrowserHostImpl::IsViewsHosted() const { return is_views_hosted_; } +bool CefBrowserHostImpl::IsPrintPreviewSupported() const { + CEF_REQUIRE_UIT(); + auto actionable_contents = GetActionableWebContents(); + if (!actionable_contents) + return false; + + if (!CefBrowserContext::GetForContext( + actionable_contents->GetBrowserContext()) + ->IsPrintPreviewSupported()) { + return false; + } + + // Print preview is not currently supported with OSR. + return !IsWindowless(); +} + void CefBrowserHostImpl::WindowDestroyed() { CEF_REQUIRE_UIT(); DCHECK(!window_destroyed_); @@ -1492,8 +1517,8 @@ void CefBrowserHostImpl::DestroyBrowser() { destruction_state_ = DESTRUCTION_STATE_COMPLETED; - // Notify that this browser has been destroyed. These must be delivered in the - // expected order. + // Notify that this browser has been destroyed. These must be delivered in + // the expected order. // 1. Notify the platform delegate. With Views this will result in a call to // CefBrowserViewDelegate::OnBrowserDestroyed(). @@ -1559,7 +1584,7 @@ CefRefPtr CefBrowserHostImpl::GetBrowserView() const { return platform_delegate_->GetBrowserView(); return nullptr; } -#endif // defined(USE_AURA) +#endif void CefBrowserHostImpl::CancelContextMenu() { CEF_REQUIRE_UIT(); @@ -1688,8 +1713,8 @@ content::BrowserContext* CefBrowserHostImpl::GetBrowserContext() { void CefBrowserHostImpl::OnSetFocus(cef_focus_source_t source) { if (CEF_CURRENTLY_ON_UIT()) { - // SetFocus() might be called while inside the OnSetFocus() callback. If so, - // don't re-enter the callback. + // SetFocus() might be called while inside the OnSetFocus() callback. If + // so, don't re-enter the callback. if (!is_in_onsetfocus_) { if (client_.get()) { CefRefPtr handler = client_->GetFocusHandler(); @@ -1720,8 +1745,8 @@ void CefBrowserHostImpl::RunFileChooser( } bool CefBrowserHostImpl::EmbedsFullscreenWidget() const { - // When using windowless rendering do not allow Flash to create its own full- - // screen widget. + // When using windowless rendering do not allow Flash to create its own + // full- screen widget. return IsWindowless(); } @@ -2071,8 +2096,8 @@ void CefBrowserHostImpl::LoadingStateChanged(content::WebContents* source, { base::AutoLock lock_scope(state_lock_); - // This method may be called multiple times in a row with |is_loading| true - // as a result of https://crrev.com/5e750ad0. Ignore the 2nd+ times. + // This method may be called multiple times in a row with |is_loading| + // true as a result of https://crrev.com/5e750ad0. Ignore the 2nd+ times. if (is_loading_ == is_loading && can_go_back_ == can_go_back && can_go_forward_ == can_go_forward) { return; @@ -2212,7 +2237,7 @@ bool CefBrowserHostImpl::HandleContextMenu( return HandleContextMenu(web_contents(), params); } -content::WebContents* CefBrowserHostImpl::GetActionableWebContents() { +content::WebContents* CefBrowserHostImpl::GetActionableWebContents() const { if (web_contents() && extensions::ExtensionsEnabled()) { content::WebContents* guest_contents = extensions::GetFullPageGuestForOwnerContents(web_contents()); @@ -2865,8 +2890,8 @@ CefBrowserHostImpl::CefBrowserHostImpl( // When navigating through the history, the restored NavigationEntry's title // will be used. If the entry ends up having the same title after we return // to it, as will usually be the case, the - // NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED will then be suppressed, since the - // NavigationEntry's title hasn't changed. + // NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED will then be suppressed, since + // the NavigationEntry's title hasn't changed. registrar_->Add(this, content::NOTIFICATION_LOAD_STOP, content::Source( &web_contents->GetController())); diff --git a/libcef/browser/browser_host_impl.h b/libcef/browser/browser_host_impl.h index 5e5270811..461d4e144 100644 --- a/libcef/browser/browser_host_impl.h +++ b/libcef/browser/browser_host_impl.h @@ -276,6 +276,9 @@ class CefBrowserHostImpl : public CefBrowserHost, // Returns true if this browser is views-hosted. bool IsViewsHosted() const; + // Returns true if this browser supports print preview. + bool IsPrintPreviewSupported() const; + // Called when the OS window hosting the browser is destroyed. void WindowDestroyed(); @@ -359,7 +362,7 @@ class CefBrowserHostImpl : public CefBrowserHost, // enabled and this browser has a full-page guest (for example, a full-page // PDF viewer extension) then the guest's WebContents will be returned. // Otherwise, the browser's WebContents will be returned. - content::WebContents* GetActionableWebContents(); + content::WebContents* GetActionableWebContents() const; enum DestructionState { DESTRUCTION_STATE_NONE = 0, diff --git a/libcef/browser/browser_main.cc b/libcef/browser/browser_main.cc index 102aeadb4..706abb7dd 100644 --- a/libcef/browser/browser_main.cc +++ b/libcef/browser/browser_main.cc @@ -16,6 +16,7 @@ #include "libcef/browser/extensions/extension_system_factory.h" #include "libcef/browser/extensions/extensions_browser_client.h" #include "libcef/browser/net/chrome_scheme_handler.h" +#include "libcef/browser/printing/constrained_window_views_client.h" #include "libcef/browser/printing/printing_message_filter.h" #include "libcef/browser/thread_util.h" #include "libcef/common/extensions/extensions_client.h" @@ -31,6 +32,7 @@ #include "chrome/browser/chrome_browser_main_extra_parts.h" #include "chrome/browser/net/system_network_context_manager.h" #include "chrome/browser/plugins/plugin_finder.h" +#include "components/constrained_window/constrained_window_views.h" #include "content/public/browser/gpu_data_manager.h" #include "extensions/browser/extension_system.h" #include "extensions/common/constants.h" @@ -73,6 +75,7 @@ CefBrowserMainParts::CefBrowserMainParts( : BrowserMainParts(), devtools_delegate_(NULL) {} CefBrowserMainParts::~CefBrowserMainParts() { + constrained_window::SetConstrainedWindowViewsClient(nullptr); for (int i = static_cast(chrome_extra_parts_.size()) - 1; i >= 0; --i) delete chrome_extra_parts_[i]; chrome_extra_parts_.clear(); @@ -101,6 +104,7 @@ void CefBrowserMainParts::PostEarlyInitialization() { } void CefBrowserMainParts::ToolkitInitialized() { + SetConstrainedWindowViewsClient(CreateCefConstrainedWindowViewsClient()); #if defined(USE_AURA) CHECK(aura::Env::GetInstance()); diff --git a/libcef/browser/browser_platform_delegate.cc b/libcef/browser/browser_platform_delegate.cc index 6e880ee61..3f7b4c490 100644 --- a/libcef/browser/browser_platform_delegate.cc +++ b/libcef/browser/browser_platform_delegate.cc @@ -6,6 +6,8 @@ #include "libcef/browser/browser_host_impl.h" #include "libcef/browser/osr/browser_platform_delegate_osr.h" +#include "libcef/browser/web_contents_dialog_helper.h" +#include "libcef/common/extensions/extensions_util.h" #include "base/logging.h" #include "content/browser/renderer_host/render_widget_host_impl.h" @@ -37,7 +39,13 @@ void CefBrowserPlatformDelegate::RenderViewCreated( void CefBrowserPlatformDelegate::BrowserCreated(CefBrowserHostImpl* browser) { DCHECK(!browser_); + DCHECK(browser); browser_ = browser; + + if (browser_->IsPrintPreviewSupported()) { + web_contents_dialog_helper_.reset( + new CefWebContentsDialogHelper(browser_->web_contents(), this)); + } } void CefBrowserPlatformDelegate::NotifyBrowserCreated() {} @@ -68,7 +76,7 @@ CefRefPtr CefBrowserPlatformDelegate::GetBrowserView() const { NOTREACHED(); return nullptr; } -#endif // defined(USE_AURA) +#endif void CefBrowserPlatformDelegate::PopupWebContentsCreated( const CefBrowserSettings& settings, @@ -209,6 +217,25 @@ void CefBrowserPlatformDelegate::AccessibilityLocationChangesReceived( NOTREACHED(); } +gfx::Point CefBrowserPlatformDelegate::GetDialogPosition( + const gfx::Size& size) { + NOTREACHED(); + return gfx::Point(); +} + +gfx::Size CefBrowserPlatformDelegate::GetMaximumDialogSize() { + NOTREACHED(); + return gfx::Size(); +} + +base::RepeatingClosure CefBrowserPlatformDelegate::GetBoundsChangedCallback() { + if (web_contents_dialog_helper_) { + return web_contents_dialog_helper_->GetBoundsChangedCallback(); + } + + return base::RepeatingClosure(); +} + // static int CefBrowserPlatformDelegate::TranslateModifiers(uint32 cef_modifiers) { int webkit_modifiers = 0; diff --git a/libcef/browser/browser_platform_delegate.h b/libcef/browser/browser_platform_delegate.h index 88d383eb4..3cedf9f9b 100644 --- a/libcef/browser/browser_platform_delegate.h +++ b/libcef/browser/browser_platform_delegate.h @@ -15,7 +15,7 @@ #include "include/views/cef_browser_view.h" #include "libcef/browser/browser_host_impl.h" -#include "base/callback.h" +#include "base/callback_forward.h" #include "content/public/browser/web_contents.h" namespace blink { @@ -42,6 +42,7 @@ class CefBrowserInfo; class CefFileDialogRunner; class CefJavaScriptDialogRunner; class CefMenuRunner; +class CefWebContentsDialogHelper; // Provides platform-specific implementations of browser functionality. All // methods are called on the browser process UI thread unless otherwise @@ -109,7 +110,7 @@ class CefBrowserPlatformDelegate { // Returns the BrowserView associated with this browser. Only used with views- // based browsers. virtual CefRefPtr GetBrowserView() const; -#endif // defined(USE_AURA) +#endif // Called after the WebContents have been created for a new popup browser // parented to this browser but before the CefBrowserHostImpl is created for @@ -274,6 +275,8 @@ class CefBrowserPlatformDelegate { const content::AXEventNotificationDetails& eventData); virtual void AccessibilityLocationChangesReceived( const std::vector& locData); + virtual gfx::Point GetDialogPosition(const gfx::Size& size); + virtual gfx::Size GetMaximumDialogSize(); protected: // Allow deletion via scoped_ptr only. @@ -282,11 +285,16 @@ class CefBrowserPlatformDelegate { CefBrowserPlatformDelegate(); virtual ~CefBrowserPlatformDelegate(); + base::RepeatingClosure GetBoundsChangedCallback(); + static int TranslateModifiers(uint32 cef_modifiers); CefBrowserHostImpl* browser_; // Not owned by this object. private: + // Used for the print preview dialog. + std::unique_ptr web_contents_dialog_helper_; + DISALLOW_COPY_AND_ASSIGN(CefBrowserPlatformDelegate); }; diff --git a/libcef/browser/chrome_browser_process_stub.cc b/libcef/browser/chrome_browser_process_stub.cc index a8a5c04e9..08b94aba3 100644 --- a/libcef/browser/chrome_browser_process_stub.cc +++ b/libcef/browser/chrome_browser_process_stub.cc @@ -16,7 +16,9 @@ #include "base/command_line.h" #include "chrome/browser/net/system_network_context_manager.h" #include "chrome/browser/policy/chrome_browser_policy_connector.h" +#include "chrome/browser/printing/background_printing_manager.h" #include "chrome/browser/printing/print_job_manager.h" +#include "chrome/browser/printing/print_preview_dialog_controller.h" #include "chrome/browser/ui/prefs/pref_watcher.h" #include "components/net_log/chrome_net_log.h" #include "components/net_log/net_export_file_writer.h" @@ -58,7 +60,6 @@ void ChromeBrowserProcessStub::OnContextInitialized() { print_job_manager_.reset(new printing::PrintJobManager()); profile_manager_.reset(new ChromeProfileManagerStub()); event_router_forwarder_ = new extensions::EventRouterForwarder(); - context_initialized_ = true; } @@ -73,6 +74,7 @@ void ChromeBrowserProcessStub::Shutdown() { // tasks to run once teardown has started. print_job_manager_->Shutdown(); print_job_manager_.reset(NULL); + print_preview_dialog_controller_ = NULL; profile_manager_.reset(); event_router_forwarder_ = nullptr; @@ -81,17 +83,26 @@ void ChromeBrowserProcessStub::Shutdown() { SystemNetworkContextManager::DeleteInstance(); } - // Release any references to |local_state_| that are held by objects - // associated with a Profile. The Profile will be deleted later. + // Release any references held by objects associated with a Profile. The + // Profile will be deleted later. for (const auto& profile : CefBrowserContext::GetAll()) { + // Release any references to |local_state_|. PrefWatcher* pref_watcher = PrefWatcher::Get(profile); if (pref_watcher) pref_watcher->Shutdown(); + + // Unregister observers for |background_printing_manager_|. + if (background_printing_manager_) { + background_printing_manager_->DeletePreviewContentsForBrowserContext( + profile); + } } local_state_.reset(); browser_policy_connector_.reset(); + background_printing_manager_.reset(); + shutdown_ = true; } @@ -254,14 +265,20 @@ printing::PrintJobManager* ChromeBrowserProcessStub::print_job_manager() { printing::PrintPreviewDialogController* ChromeBrowserProcessStub::print_preview_dialog_controller() { - NOTREACHED(); - return NULL; + if (!print_preview_dialog_controller_.get()) { + print_preview_dialog_controller_ = + new printing::PrintPreviewDialogController(); + } + return print_preview_dialog_controller_.get(); } printing::BackgroundPrintingManager* ChromeBrowserProcessStub::background_printing_manager() { - NOTREACHED(); - return NULL; + if (!background_printing_manager_.get()) { + background_printing_manager_.reset( + new printing::BackgroundPrintingManager()); + } + return background_printing_manager_.get(); } IntranetRedirectDetector* diff --git a/libcef/browser/chrome_browser_process_stub.h b/libcef/browser/chrome_browser_process_stub.h index 3feaa74f3..762098c17 100644 --- a/libcef/browser/chrome_browser_process_stub.h +++ b/libcef/browser/chrome_browser_process_stub.h @@ -118,6 +118,10 @@ class ChromeBrowserProcessStub : public BrowserProcess { std::unique_ptr profile_manager_; scoped_refptr event_router_forwarder_; std::unique_ptr net_log_; + scoped_refptr + print_preview_dialog_controller_; + std::unique_ptr + background_printing_manager_; std::unique_ptr net_export_file_writer_; std::unique_ptr local_state_; // Must be destroyed after |local_state_|. diff --git a/libcef/browser/content_browser_client.cc b/libcef/browser/content_browser_client.cc index a46087f3b..7b381998c 100644 --- a/libcef/browser/content_browser_client.cc +++ b/libcef/browser/content_browser_client.cc @@ -803,6 +803,7 @@ void CefContentBrowserClient::AppendExtraCommandLineSwitches( switches::kDisableExtensions, switches::kDisablePdfExtension, switches::kDisablePlugins, + switches::kDisablePrintPreview, switches::kDisableScrollBounce, switches::kDisableSpellChecking, switches::kEnableSpeechInput, @@ -817,15 +818,22 @@ void CefContentBrowserClient::AppendExtraCommandLineSwitches( base::size(kSwitchNames)); if (extensions::ExtensionsEnabled()) { - // Based on ChromeContentBrowserClientExtensionsPart:: - // AppendExtraRendererCommandLineSwitches content::RenderProcessHost* process = content::RenderProcessHost::FromID(child_process_id); - content::BrowserContext* browser_context = - process ? process->GetBrowserContext() : NULL; - if (browser_context && extensions::ProcessMap::Get(browser_context) - ->Contains(process->GetID())) { - command_line->AppendSwitch(extensions::switches::kExtensionProcess); + CefBrowserContext* context = + process + ? CefBrowserContext::GetForContext(process->GetBrowserContext()) + : nullptr; + if (context) { + if (context->IsPrintPreviewSupported()) { + command_line->AppendSwitch(switches::kEnablePrintPreview); + } + + // Based on ChromeContentBrowserClientExtensionsPart:: + // AppendExtraRendererCommandLineSwitches + if (extensions::ProcessMap::Get(context)->Contains(process->GetID())) { + command_line->AppendSwitch(extensions::switches::kExtensionProcess); + } } } } else { diff --git a/libcef/browser/extensions/browser_extensions_util.cc b/libcef/browser/extensions/browser_extensions_util.cc index 7c6ec9078..7472969cd 100644 --- a/libcef/browser/extensions/browser_extensions_util.cc +++ b/libcef/browser/extensions/browser_extensions_util.cc @@ -9,6 +9,8 @@ #include "libcef/browser/thread_util.h" #include "libcef/common/extensions/extensions_util.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/printing/print_preview_dialog_controller.h" #include "content/browser/browser_plugin/browser_plugin_embedder.h" #include "content/browser/browser_plugin/browser_plugin_guest.h" #include "content/browser/web_contents/web_contents_impl.h" @@ -58,7 +60,11 @@ content::WebContents* GetOwnerForGuestContents(content::WebContents* guest) { guest_impl->GetBrowserPluginGuest(); if (plugin_guest) return plugin_guest->embedder_web_contents(); - return NULL; + + // Maybe it's a print preview dialog. + auto print_preview_controller = + g_browser_process->print_preview_dialog_controller(); + return print_preview_controller->GetInitiator(guest); } CefRefPtr GetOwnerBrowserForFrameRoute( diff --git a/libcef/browser/native/browser_platform_delegate_native_linux.cc b/libcef/browser/native/browser_platform_delegate_native_linux.cc index e7a4a7247..5327acc46 100644 --- a/libcef/browser/native/browser_platform_delegate_native_linux.cc +++ b/libcef/browser/native/browser_platform_delegate_native_linux.cc @@ -89,7 +89,8 @@ bool CefBrowserPlatformDelegateNativeLinux::CreateHostWindow() { browser_->AddRef(); CefWindowDelegateView* delegate_view = new CefWindowDelegateView( - GetBackgroundColor(), window_x11_->TopLevelAlwaysOnTop()); + GetBackgroundColor(), window_x11_->TopLevelAlwaysOnTop(), + GetBoundsChangedCallback()); delegate_view->Init(window_info_.window, browser_->web_contents(), gfx::Rect(gfx::Point(), rect.size())); @@ -410,3 +411,14 @@ void CefBrowserPlatformDelegateNativeLinux::TranslateMouseEvent( result.pointer_type = blink::WebPointerProperties::PointerType::kMouse; } + +gfx::Point CefBrowserPlatformDelegateNativeLinux::GetDialogPosition( + const gfx::Size& size) { + const gfx::Size& max_size = GetMaximumDialogSize(); + return gfx::Point((max_size.width() - size.width()) / 2, + (max_size.height() - size.height()) / 2); +} + +gfx::Size CefBrowserPlatformDelegateNativeLinux::GetMaximumDialogSize() { + return GetWindowWidget()->GetWindowBoundsInScreen().size(); +} \ No newline at end of file diff --git a/libcef/browser/native/browser_platform_delegate_native_linux.h b/libcef/browser/native/browser_platform_delegate_native_linux.h index b001a21b0..2249114bb 100644 --- a/libcef/browser/native/browser_platform_delegate_native_linux.h +++ b/libcef/browser/native/browser_platform_delegate_native_linux.h @@ -49,6 +49,8 @@ class CefBrowserPlatformDelegateNativeLinux CefEventHandle GetEventHandle( const content::NativeWebKeyboardEvent& event) const override; std::unique_ptr CreateMenuRunner() override; + gfx::Point GetDialogPosition(const gfx::Size& size) override; + gfx::Size GetMaximumDialogSize() override; private: void TranslateMouseEvent(blink::WebMouseEvent& result, diff --git a/libcef/browser/native/browser_platform_delegate_native_mac.h b/libcef/browser/native/browser_platform_delegate_native_mac.h index 2a687e746..11ee14780 100644 --- a/libcef/browser/native/browser_platform_delegate_native_mac.h +++ b/libcef/browser/native/browser_platform_delegate_native_mac.h @@ -44,6 +44,8 @@ class CefBrowserPlatformDelegateNativeMac std::unique_ptr CreateJavaScriptDialogRunner() override; std::unique_ptr CreateMenuRunner() override; + gfx::Point GetDialogPosition(const gfx::Size& size) override; + gfx::Size GetMaximumDialogSize() override; private: void TranslateMouseEvent(blink::WebMouseEvent& result, diff --git a/libcef/browser/native/browser_platform_delegate_native_mac.mm b/libcef/browser/native/browser_platform_delegate_native_mac.mm index 558c84fb3..4fcb82aa6 100644 --- a/libcef/browser/native/browser_platform_delegate_native_mac.mm +++ b/libcef/browser/native/browser_platform_delegate_native_mac.mm @@ -481,3 +481,16 @@ void CefBrowserPlatformDelegateNativeMac::TranslateMouseEvent( result.pointer_type = blink::WebPointerProperties::PointerType::kMouse; } + +gfx::Point CefBrowserPlatformDelegateNativeMac::GetDialogPosition( + const gfx::Size& size) { + // Dialogs are always re-positioned by the constrained window sheet controller + // so nothing interesting to return yet. + return gfx::Point(); +} + +gfx::Size CefBrowserPlatformDelegateNativeMac::GetMaximumDialogSize() { + // The dialog should try to fit within the overlay for the web contents. + // Note that, for things like print preview, this is just a suggested maximum. + return browser_->web_contents()->GetContainerBounds().size(); +} diff --git a/libcef/browser/native/browser_platform_delegate_native_win.cc b/libcef/browser/native/browser_platform_delegate_native_win.cc index 649b24a12..2cf423233 100644 --- a/libcef/browser/native/browser_platform_delegate_native_win.cc +++ b/libcef/browser/native/browser_platform_delegate_native_win.cc @@ -201,8 +201,8 @@ bool CefBrowserPlatformDelegateNativeWin::CreateHostWindow() { bool always_on_top = (top_level_window_ex_styles & WS_EX_TOPMOST) == WS_EX_TOPMOST; - CefWindowDelegateView* delegate_view = - new CefWindowDelegateView(GetBackgroundColor(), always_on_top); + CefWindowDelegateView* delegate_view = new CefWindowDelegateView( + GetBackgroundColor(), always_on_top, GetBoundsChangedCallback()); delegate_view->Init(window_info_.window, browser_->web_contents(), gfx::Rect(0, 0, point.x(), point.y())); @@ -594,6 +594,17 @@ void CefBrowserPlatformDelegateNativeWin::TranslateMouseEvent( result.pointer_type = blink::WebPointerProperties::PointerType::kMouse; } +gfx::Point CefBrowserPlatformDelegateNativeWin::GetDialogPosition( + const gfx::Size& size) { + const gfx::Size& max_size = GetMaximumDialogSize(); + return gfx::Point((max_size.width() - size.width()) / 2, + (max_size.height() - size.height()) / 2); +} + +gfx::Size CefBrowserPlatformDelegateNativeWin::GetMaximumDialogSize() { + return GetWindowWidget()->GetWindowBoundsInScreen().size(); +} + // static void CefBrowserPlatformDelegateNativeWin::RegisterWindowClass() { static bool registered = false; diff --git a/libcef/browser/native/browser_platform_delegate_native_win.h b/libcef/browser/native/browser_platform_delegate_native_win.h index 2be8d8c7f..a1d95e9db 100644 --- a/libcef/browser/native/browser_platform_delegate_native_win.h +++ b/libcef/browser/native/browser_platform_delegate_native_win.h @@ -51,6 +51,8 @@ class CefBrowserPlatformDelegateNativeWin std::unique_ptr CreateJavaScriptDialogRunner() override; std::unique_ptr CreateMenuRunner() override; + gfx::Point GetDialogPosition(const gfx::Size& size) override; + gfx::Size GetMaximumDialogSize() override; private: void TranslateMouseEvent(blink::WebMouseEvent& result, diff --git a/libcef/browser/native/window_delegate_view.cc b/libcef/browser/native/window_delegate_view.cc index 1da7a6c4c..2470aa355 100644 --- a/libcef/browser/native/window_delegate_view.cc +++ b/libcef/browser/native/window_delegate_view.cc @@ -12,11 +12,14 @@ #include "ui/views/layout/fill_layout.h" #include "ui/views/widget/widget.h" -CefWindowDelegateView::CefWindowDelegateView(SkColor background_color, - bool always_on_top) +CefWindowDelegateView::CefWindowDelegateView( + SkColor background_color, + bool always_on_top, + base::RepeatingClosure on_bounds_changed) : background_color_(background_color), web_view_(NULL), - always_on_top_(always_on_top) {} + always_on_top_(always_on_top), + on_bounds_changed_(on_bounds_changed) {} void CefWindowDelegateView::Init(gfx::AcceleratedWidget parent_widget, content::WebContents* web_contents, @@ -71,3 +74,9 @@ void CefWindowDelegateView::ViewHierarchyChanged( if (details.is_add && details.child == this) InitContent(); } + +void CefWindowDelegateView::OnBoundsChanged(const gfx::Rect& previous_bounds) { + views::WidgetDelegateView::OnBoundsChanged(previous_bounds); + if (!on_bounds_changed_.is_null()) + on_bounds_changed_.Run(); +} diff --git a/libcef/browser/native/window_delegate_view.h b/libcef/browser/native/window_delegate_view.h index 57ff0ec57..3fb25a63d 100644 --- a/libcef/browser/native/window_delegate_view.h +++ b/libcef/browser/native/window_delegate_view.h @@ -20,7 +20,9 @@ class WebView; // will be deleted automatically when the associated root window is destroyed. class CefWindowDelegateView : public views::WidgetDelegateView { public: - CefWindowDelegateView(SkColor background_color, bool always_on_top); + CefWindowDelegateView(SkColor background_color, + bool always_on_top, + base::RepeatingClosure on_bounds_changed); // Create the Widget and associated root window. void Init(gfx::AcceleratedWidget parent_widget, @@ -39,11 +41,13 @@ class CefWindowDelegateView : public views::WidgetDelegateView { // View methods: void ViewHierarchyChanged( const views::ViewHierarchyChangedDetails& details) override; + void OnBoundsChanged(const gfx::Rect& previous_bounds) override; private: SkColor background_color_; views::WebView* web_view_; bool always_on_top_; + base::RepeatingClosure on_bounds_changed_; DISALLOW_COPY_AND_ASSIGN(CefWindowDelegateView); }; diff --git a/libcef/browser/net/chrome_scheme_handler.cc b/libcef/browser/net/chrome_scheme_handler.cc index daf838f37..12016aa70 100644 --- a/libcef/browser/net/chrome_scheme_handler.cc +++ b/libcef/browser/net/chrome_scheme_handler.cc @@ -86,6 +86,7 @@ const char* kAllowedWebUIHosts[] = { chrome::kChromeUINetInternalsHost, content::kChromeUINetworkErrorHost, content::kChromeUINetworkErrorsListingHost, + chrome::kChromeUIPrintHost, content::kChromeUIResourcesHost, content::kChromeUIServiceWorkerInternalsHost, chrome::kChromeUISystemInfoHost, diff --git a/libcef/browser/osr/browser_platform_delegate_osr.cc b/libcef/browser/osr/browser_platform_delegate_osr.cc index ca93104b2..66f63b019 100644 --- a/libcef/browser/osr/browser_platform_delegate_osr.cc +++ b/libcef/browser/osr/browser_platform_delegate_osr.cc @@ -39,6 +39,8 @@ void CefBrowserPlatformDelegateOsr::CreateViewForWebContents( void CefBrowserPlatformDelegateOsr::WebContentsCreated( content::WebContents* web_contents) { + CefBrowserPlatformDelegate::WebContentsCreated(web_contents); + DCHECK(view_osr_); DCHECK(!view_osr_->web_contents()); diff --git a/libcef/browser/prefs/browser_prefs.cc b/libcef/browser/prefs/browser_prefs.cc index 287004fe2..4ca863782 100644 --- a/libcef/browser/prefs/browser_prefs.cc +++ b/libcef/browser/prefs/browser_prefs.cc @@ -10,6 +10,7 @@ #include "libcef/browser/prefs/pref_store.h" #include "libcef/browser/prefs/renderer_prefs.h" #include "libcef/common/cef_switches.h" +#include "libcef/common/extensions/extensions_util.h" #include "libcef/common/net_service/util.h" #include "base/command_line.h" @@ -18,6 +19,7 @@ #include "base/task/post_task.h" #include "base/values.h" #include "chrome/browser/accessibility/accessibility_ui.h" +#include "chrome/browser/download/download_prefs.h" #include "chrome/browser/net/prediction_options.h" #include "chrome/browser/net/profile_network_context_service.h" #include "chrome/browser/net/system_network_context_manager.h" @@ -29,6 +31,7 @@ #include "chrome/browser/supervised_user/supervised_user_settings_service.h" #include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h" #include "chrome/browser/themes/theme_service.h" +#include "chrome/browser/ui/webui/print_preview/sticky_settings.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "chrome/grit/locale_settings.h" @@ -191,6 +194,10 @@ std::unique_ptr CreatePrefService(Profile* profile, // Based on chrome/browser/ui/browser_ui_prefs.cc RegisterBrowserPrefs. registry->RegisterBooleanPref(prefs::kAllowFileSelectionDialogs, true); + // From Chrome::RegisterBrowserUserPrefs. + registry->RegisterBooleanPref(prefs::kPrintPreviewUseSystemDefaultPrinter, + true); + if (command_line->HasSwitch(switches::kEnablePreferenceTesting)) { // Preferences used with unit tests. registry->RegisterBooleanPref("test.bool", true); @@ -225,6 +232,13 @@ std::unique_ptr CreatePrefService(Profile* profile, // Print preferences. // Based on ProfileImpl::RegisterProfilePrefs. registry->RegisterBooleanPref(prefs::kPrintingEnabled, true); + registry->RegisterBooleanPref(prefs::kPrintPreviewDisabled, + !extensions::PrintPreviewEnabled()); + registry->RegisterStringPref( + prefs::kPrintPreviewDefaultDestinationSelectionRules, std::string()); + registry->RegisterBooleanPref(prefs::kCloudPrintSubmitEnabled, false); + printing::StickySettings::RegisterProfilePrefs(registry.get()); + DownloadPrefs::RegisterProfilePrefs(registry.get()); // Cache preferences. // Based on ProfileImpl::RegisterProfilePrefs. diff --git a/libcef/browser/printing/constrained_window_views_client.cc b/libcef/browser/printing/constrained_window_views_client.cc new file mode 100644 index 000000000..1670f411d --- /dev/null +++ b/libcef/browser/printing/constrained_window_views_client.cc @@ -0,0 +1,42 @@ +// Copyright 2014 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/printing/constrained_window_views_client.h" + +#include "base/logging.h" +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "chrome/browser/platform_util.h" +#include "chrome/browser/ui/browser_finder.h" +#include "components/web_modal/web_contents_modal_dialog_host.h" + +namespace { + +class CefConstrainedWindowViewsClient + : public constrained_window::ConstrainedWindowViewsClient { + public: + CefConstrainedWindowViewsClient() {} + ~CefConstrainedWindowViewsClient() override {} + + private: + // ConstrainedWindowViewsClient: + web_modal::ModalDialogHost* GetModalDialogHost( + gfx::NativeWindow parent) override { + NOTREACHED(); + return nullptr; + } + gfx::NativeView GetDialogHostView(gfx::NativeWindow parent) override { + NOTREACHED(); + return gfx::NativeView(); + } + + DISALLOW_COPY_AND_ASSIGN(CefConstrainedWindowViewsClient); +}; + +} // namespace + +std::unique_ptr +CreateCefConstrainedWindowViewsClient() { + return base::WrapUnique(new CefConstrainedWindowViewsClient); +} \ No newline at end of file diff --git a/libcef/browser/printing/constrained_window_views_client.h b/libcef/browser/printing/constrained_window_views_client.h new file mode 100644 index 000000000..0f1878482 --- /dev/null +++ b/libcef/browser/printing/constrained_window_views_client.h @@ -0,0 +1,16 @@ +// Copyright 2014 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_PRINTING_CONSTRAINED_WINDOW_VIEWS_CLIENT_H_ +#define CEF_LIBCEF_BROWSER_PRINTING_CONSTRAINED_WINDOW_VIEWS_CLIENT_H_ + +#include + +#include "components/constrained_window/constrained_window_views_client.h" + +// Creates a ConstrainedWindowViewsClient for the Chrome environment. +std::unique_ptr +CreateCefConstrainedWindowViewsClient(); + +#endif // CEF_LIBCEF_BROWSER_PRINTING_CONSTRAINED_WINDOW_VIEWS_CLIENT_H_ \ No newline at end of file diff --git a/libcef/browser/printing/print_view_manager.cc b/libcef/browser/printing/print_view_manager.cc index 1246570c7..9001c940f 100644 --- a/libcef/browser/printing/print_view_manager.cc +++ b/libcef/browser/printing/print_view_manager.cc @@ -3,7 +3,12 @@ // found in the LICENSE file. #include "libcef/browser/printing/print_view_manager.h" + #include "include/internal/cef_types_wrappers.h" +#include "libcef/browser/browser_info.h" +#include "libcef/browser/browser_info_manager.h" +#include "libcef/browser/download_manager_delegate.h" +#include "libcef/browser/extensions/extension_web_contents_observer.h" #include #include @@ -15,13 +20,23 @@ #include "base/task/post_task.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/printing/print_job_manager.h" +#include "chrome/browser/printing/print_preview_dialog_controller.h" +#include "chrome/browser/printing/print_preview_message_handler.h" +#include "chrome/browser/printing/print_view_manager.h" #include "chrome/browser/printing/printer_query.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/webui/print_preview/print_preview_ui.h" #include "components/printing/common/print_messages.h" +#include "content/browser/download/download_manager_impl.h" +#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/download_manager.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" +#include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_observer.h" #include "printing/metafile_skia.h" #include "libcef/browser/thread_util.h" @@ -158,7 +173,10 @@ struct CefPrintViewManager::PdfPrintState { }; CefPrintViewManager::CefPrintViewManager(content::WebContents* web_contents) - : CefPrintViewManagerBase(web_contents) {} + : WebContentsObserver(web_contents) { + PrintViewManager::CreateForWebContents(web_contents); + PrintPreviewMessageHandler::CreateForWebContents(web_contents); +} CefPrintViewManager::~CefPrintViewManager() { TerminatePdfPrintJob(); @@ -194,57 +212,87 @@ bool CefPrintViewManager::PrintToPDF(content::RenderFrameHost* rfh, return true; } +bool CefPrintViewManager::PrintPreviewNow(content::RenderFrameHost* rfh, + bool has_selection) { + return PrintViewManager::FromWebContents(web_contents()) + ->PrintPreviewNow(rfh, has_selection); +} + void CefPrintViewManager::RenderFrameDeleted( content::RenderFrameHost* render_frame_host) { if (pdf_print_state_ && render_frame_host == pdf_print_state_->printing_rfh_) { TerminatePdfPrintJob(); } - CefPrintViewManagerBase::RenderFrameDeleted(render_frame_host); } void CefPrintViewManager::NavigationStopped() { TerminatePdfPrintJob(); - CefPrintViewManagerBase::NavigationStopped(); } void CefPrintViewManager::RenderProcessGone(base::TerminationStatus status) { TerminatePdfPrintJob(); - CefPrintViewManagerBase::RenderProcessGone(status); } bool CefPrintViewManager::OnMessageReceived( const IPC::Message& message, content::RenderFrameHost* render_frame_host) { bool handled = true; + if (!pdf_print_state_) { + IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(CefPrintViewManager, message, + render_frame_host) + IPC_MESSAGE_HANDLER(PrintHostMsg_RequestPrintPreview, + OnRequestPrintPreview) + IPC_MESSAGE_HANDLER(PrintHostMsg_ShowScriptedPrintPreview, + OnShowScriptedPrintPreview) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return false; + } + IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(CefPrintViewManager, message, render_frame_host) - IPC_MESSAGE_HANDLER(PrintHostMsg_DidShowPrintDialog, OnDidShowPrintDialog) - IPC_MESSAGE_HANDLER(PrintHostMsg_RequestPrintPreview, OnRequestPrintPreview) + IPC_MESSAGE_HANDLER(PrintHostMsg_DidShowPrintDialog, + OnDidShowPrintDialog_PrintToPdf) + IPC_MESSAGE_HANDLER(PrintHostMsg_RequestPrintPreview, + OnRequestPrintPreview_PrintToPdf) IPC_MESSAGE_HANDLER(PrintHostMsg_MetafileReadyForPrinting, - OnMetafileReadyForPrinting) + OnMetafileReadyForPrinting_PrintToPdf) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() - return handled || - CefPrintViewManagerBase::OnMessageReceived(message, render_frame_host); + return handled; +} +void CefPrintViewManager::OnRequestPrintPreview( + content::RenderFrameHost* rfh, + const PrintHostMsg_RequestPrintPreview_Params&) { + InitializePrintPreview(rfh->GetFrameTreeNodeId()); } -void CefPrintViewManager::OnDidShowPrintDialog(content::RenderFrameHost* rfh) {} +void CefPrintViewManager::OnShowScriptedPrintPreview( + content::RenderFrameHost* rfh, + bool source_is_modifiable) { + InitializePrintPreview(rfh->GetFrameTreeNodeId()); +} -void CefPrintViewManager::OnRequestPrintPreview( +void CefPrintViewManager::OnDidShowPrintDialog_PrintToPdf( + content::RenderFrameHost* rfh) {} + +void CefPrintViewManager::OnRequestPrintPreview_PrintToPdf( + content::RenderFrameHost* rfh, const PrintHostMsg_RequestPrintPreview_Params&) { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!pdf_print_state_) return; - pdf_print_state_->printing_rfh_->Send( - new PrintMsg_PrintPreview(pdf_print_state_->printing_rfh_->GetRoutingID(), - pdf_print_state_->settings_)); + DCHECK_EQ(pdf_print_state_->printing_rfh_, rfh); + + rfh->Send(new PrintMsg_PrintPreview(rfh->GetRoutingID(), + pdf_print_state_->settings_)); } -void CefPrintViewManager::OnMetafileReadyForPrinting( - content::RenderFrameHost* render_frame_host, +void CefPrintViewManager::OnMetafileReadyForPrinting_PrintToPdf( + content::RenderFrameHost* rfh, const PrintHostMsg_DidPreviewDocument_Params& params, const PrintHostMsg_PreviewIds& ids) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -253,8 +301,9 @@ void CefPrintViewManager::OnMetafileReadyForPrinting( if (!pdf_print_state_) return; - pdf_print_state_->printing_rfh_->Send(new PrintMsg_ClosePrintPreviewDialog( - pdf_print_state_->printing_rfh_->GetRoutingID())); + DCHECK_EQ(pdf_print_state_->printing_rfh_, rfh); + + rfh->Send(new PrintMsg_ClosePrintPreviewDialog(rfh->GetRoutingID())); auto shared_buf = base::RefCountedSharedMemoryMapping::CreateFromWholeRegion( params.content.metafile_data_region); @@ -289,5 +338,72 @@ void CefPrintViewManager::TerminatePdfPrintJob() { pdf_print_state_.reset(); } +void CefPrintViewManager::InitializePrintPreview(int frame_tree_node_id) { + PrintPreviewDialogController* dialog_controller = + PrintPreviewDialogController::GetInstance(); + if (!dialog_controller) + return; + + dialog_controller->PrintPreview(web_contents()); + + content::WebContents* preview_contents = + dialog_controller->GetPrintPreviewForContents(web_contents()); + + extensions::CefExtensionWebContentsObserver::CreateForWebContents( + preview_contents); + + PrintPreviewHelper::CreateForWebContents(preview_contents); + PrintPreviewHelper::FromWebContents(preview_contents) + ->Initialize(frame_tree_node_id); +} + WEB_CONTENTS_USER_DATA_KEY_IMPL(CefPrintViewManager) + +// CefPrintViewManager::PrintPreviewHelper + +CefPrintViewManager::PrintPreviewHelper::PrintPreviewHelper( + content::WebContents* contents) + : content::WebContentsObserver(contents) {} + +void CefPrintViewManager::PrintPreviewHelper::Initialize( + int parent_frame_tree_node_id) { + DCHECK_EQ(parent_frame_tree_node_id_, + content::RenderFrameHost::kNoFrameTreeNodeId); + DCHECK_NE(parent_frame_tree_node_id, + content::RenderFrameHost::kNoFrameTreeNodeId); + parent_frame_tree_node_id_ = parent_frame_tree_node_id; + + auto context = web_contents()->GetBrowserContext(); + auto manager = content::BrowserContext::GetDownloadManager(context); + + if (!context->GetDownloadManagerDelegate()) { + manager->SetDelegate(new CefDownloadManagerDelegate(manager)); + } + + auto browser_info = + CefBrowserInfoManager::GetInstance()->GetBrowserInfoForFrameTreeNode( + parent_frame_tree_node_id_); + DCHECK(browser_info); + if (!browser_info) + return; + + // Associate guest state information with the owner browser. + browser_info->MaybeCreateFrame(web_contents()->GetMainFrame(), + true /* is_guest_view */); +} + +void CefPrintViewManager::PrintPreviewHelper::WebContentsDestroyed() { + auto browser_info = + CefBrowserInfoManager::GetInstance()->GetBrowserInfoForFrameTreeNode( + parent_frame_tree_node_id_); + DCHECK(browser_info); + if (!browser_info) + return; + + // Disassociate guest state information with the owner browser. + browser_info->RemoveFrame(web_contents()->GetMainFrame()); +} + +WEB_CONTENTS_USER_DATA_KEY_IMPL(CefPrintViewManager::PrintPreviewHelper) + } // namespace printing diff --git a/libcef/browser/printing/print_view_manager.h b/libcef/browser/printing/print_view_manager.h index 90d3c3984..e341103f9 100644 --- a/libcef/browser/printing/print_view_manager.h +++ b/libcef/browser/printing/print_view_manager.h @@ -6,16 +6,19 @@ #define CEF_LIBCEF_BROWSER_PRINTING_PRINT_VIEW_MANAGER_H_ #include "include/internal/cef_types_wrappers.h" -#include "libcef/browser/printing/print_view_manager_base.h" #include "base/macros.h" +#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" namespace content { class RenderFrameHost; class RenderProcessHost; +class WebContentsObserver; } // namespace content +class CefBrowserInfo; + struct PrintHostMsg_DidPreviewDocument_Params; struct PrintHostMsg_PreviewIds; struct PrintHostMsg_RequestPrintPreview_Params; @@ -24,7 +27,7 @@ namespace printing { // Manages the print commands for a WebContents. class CefPrintViewManager - : public CefPrintViewManagerBase, + : public content::WebContentsObserver, public content::WebContentsUserData { public: ~CefPrintViewManager() override; @@ -38,6 +41,9 @@ class CefPrintViewManager const CefPdfPrintSettings& settings, const PdfPrintCallback& callback); + // Call to Chrome's PrintViewManager. + bool PrintPreviewNow(content::RenderFrameHost* rfh, bool has_selection); + // content::WebContentsObserver implementation. void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override; void NavigationStopped() override; @@ -45,22 +51,47 @@ class CefPrintViewManager bool OnMessageReceived(const IPC::Message& message, content::RenderFrameHost* render_frame_host) override; + // Used to track the lifespan of the print preview WebContents. + class PrintPreviewHelper + : public content::WebContentsObserver, + public content::WebContentsUserData { + public: + void Initialize(int parent_frame_tree_node_id); + void WebContentsDestroyed() override; + + private: + friend class content::WebContentsUserData; + + explicit PrintPreviewHelper(content::WebContents* contents); + + int parent_frame_tree_node_id_ = -1; + + WEB_CONTENTS_USER_DATA_KEY_DECL(); + DISALLOW_COPY_AND_ASSIGN(PrintPreviewHelper); + }; + private: explicit CefPrintViewManager(content::WebContents* web_contents); friend class content::WebContentsUserData; // IPC Message handlers. - void OnDidShowPrintDialog(content::RenderFrameHost* rfh); - void OnRequestPrintPreview(const PrintHostMsg_RequestPrintPreview_Params&); - void OnMetafileReadyForPrinting( - content::RenderFrameHost* render_frame_host, + void OnRequestPrintPreview(content::RenderFrameHost* rfh, + const PrintHostMsg_RequestPrintPreview_Params&); + void OnShowScriptedPrintPreview(content::RenderFrameHost* rfh, + bool source_is_modifiable); + void OnRequestPrintPreview_PrintToPdf( + content::RenderFrameHost* rfh, + const PrintHostMsg_RequestPrintPreview_Params&); + void OnDidShowPrintDialog_PrintToPdf(content::RenderFrameHost* rfh); + void OnMetafileReadyForPrinting_PrintToPdf( + content::RenderFrameHost* rfh, const PrintHostMsg_DidPreviewDocument_Params& params, const PrintHostMsg_PreviewIds& ids); - + void InitializePrintPreview(int frame_tree_node_id); void TerminatePdfPrintJob(); // Used for printing to PDF. Only accessed on the browser process UI thread. - int next_pdf_request_id_ = -1; + int next_pdf_request_id_ = content::RenderFrameHost::kNoFrameTreeNodeId; struct PdfPrintState; std::unique_ptr pdf_print_state_; WEB_CONTENTS_USER_DATA_KEY_DECL(); @@ -69,4 +100,4 @@ class CefPrintViewManager } // namespace printing -#endif // CEF_LIBCEF_BROWSER_PRINTING_PRINT_VIEW_MANAGER_H_ +#endif // CEF_LIBCEF_BROWSER_PRINTING_PRINT_VIEW_MANAGER_H_ \ No newline at end of file diff --git a/libcef/browser/printing/print_view_manager_base.cc b/libcef/browser/printing/print_view_manager_base.cc deleted file mode 100644 index 2d732f315..000000000 --- a/libcef/browser/printing/print_view_manager_base.cc +++ /dev/null @@ -1,559 +0,0 @@ -// Copyright 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 "libcef/browser/printing/print_view_manager_base.h" - -#include -#include - -#include "base/auto_reset.h" -#include "base/bind.h" -#include "base/location.h" -#include "base/memory/ref_counted_memory.h" -#include "base/memory/shared_memory.h" -#include "base/message_loop/message_loop_current.h" -#include "base/run_loop.h" -#include "base/single_thread_task_runner.h" -#include "base/strings/utf_string_conversions.h" -#include "base/task/post_task.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/timer/timer.h" -#include "build/build_config.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/printing/print_job.h" -#include "chrome/browser/printing/print_job_manager.h" -#include "chrome/browser/printing/printer_query.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/common/pref_names.h" -#include "chrome/grit/generated_resources.h" -#include "components/prefs/pref_service.h" -#include "components/printing/browser/print_composite_client.h" -#include "components/printing/browser/print_manager_utils.h" -#include "components/printing/common/print_messages.h" -#include "components/services/pdf_compositor/public/cpp/pdf_service_mojo_types.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/notification_details.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_source.h" -#include "content/public/browser/render_frame_host.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/browser/render_view_host.h" -#include "content/public/browser/web_contents.h" -#include "mojo/public/cpp/system/buffer.h" -#include "printing/buildflags/buildflags.h" -#include "printing/metafile_skia.h" -#include "printing/print_settings.h" -#include "printing/printed_document.h" -#include "ui/base/l10n/l10n_util.h" - -#if defined(OS_WIN) -#include "base/command_line.h" -#include "chrome/common/chrome_features.h" -#endif - -using base::TimeDelta; -using content::BrowserThread; - -namespace printing { - -CefPrintViewManagerBase::CefPrintViewManagerBase( - content::WebContents* web_contents) - : PrintManager(web_contents), - printing_rfh_(nullptr), - printing_succeeded_(false), - inside_inner_message_loop_(false), - queue_(g_browser_process->print_job_manager()->queue()), - weak_ptr_factory_(this) { - DCHECK(queue_); - Profile* profile = - Profile::FromBrowserContext(web_contents->GetBrowserContext()); - printing_enabled_.Init( - prefs::kPrintingEnabled, profile->GetPrefs(), - base::Bind(&CefPrintViewManagerBase::UpdatePrintingEnabled, - weak_ptr_factory_.GetWeakPtr())); -} - -CefPrintViewManagerBase::~CefPrintViewManagerBase() { - ReleasePrinterQuery(); - DisconnectFromCurrentPrintJob(); -} - -bool CefPrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh) { - DisconnectFromCurrentPrintJob(); - - SetPrintingRFH(rfh); - int32_t id = rfh->GetRoutingID(); - return PrintNowInternal(rfh, std::make_unique(id)); -} - -void CefPrintViewManagerBase::PrintDocument( - const scoped_refptr& print_data, - const gfx::Size& page_size, - const gfx::Rect& content_area, - const gfx::Point& offsets) { -#if defined(OS_WIN) - print_job_->StartConversionToNativeFormat(print_data, page_size, content_area, - offsets); -#else - std::unique_ptr metafile = std::make_unique(); - CHECK(metafile->InitFromData(print_data->front(), print_data->size())); - - // Update the rendered document. It will send notifications to the listener. - PrintedDocument* document = print_job_->document(); - document->SetDocument(std::move(metafile), page_size, content_area); - ShouldQuitFromInnerMessageLoop(); -#endif -} - -void CefPrintViewManagerBase::UpdatePrintingEnabled() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - // The Unretained() is safe because ForEachFrame() is synchronous. - web_contents()->ForEachFrame(base::BindRepeating( - &CefPrintViewManagerBase::SendPrintingEnabled, base::Unretained(this), - printing_enabled_.GetValue())); -} - -void CefPrintViewManagerBase::NavigationStopped() { - // Cancel the current job, wait for the worker to finish. - TerminatePrintJob(true); -} - -base::string16 CefPrintViewManagerBase::RenderSourceName() { - base::string16 name(web_contents()->GetTitle()); - if (name.empty()) - name = l10n_util::GetStringUTF16(IDS_DEFAULT_PRINT_DOCUMENT_TITLE); - return name; -} - -void CefPrintViewManagerBase::OnDidGetPrintedPagesCount(int cookie, - int number_pages) { - PrintManager::OnDidGetPrintedPagesCount(cookie, number_pages); - OpportunisticallyCreatePrintJob(cookie); -} - -bool CefPrintViewManagerBase::PrintJobHasDocument(int cookie) { - if (!OpportunisticallyCreatePrintJob(cookie)) - return false; - - // These checks may fail since we are completely asynchronous. Old spurious - // messages can be received if one of the processes is overloaded. - PrintedDocument* document = print_job_->document(); - return document && document->cookie() == cookie; -} - -void CefPrintViewManagerBase::OnComposePdfDone( - const gfx::Size& page_size, - const gfx::Rect& content_area, - const gfx::Point& physical_offsets, - mojom::PdfCompositor::Status status, - base::ReadOnlySharedMemoryRegion region) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (status != mojom::PdfCompositor::Status::SUCCESS) { - DLOG(ERROR) << "Compositing pdf failed with error " << status; - return; - } - - if (!print_job_->document()) - return; - - scoped_refptr data = - base::RefCountedSharedMemoryMapping::CreateFromWholeRegion(region); - if (!data) - return; - - PrintDocument(data, page_size, content_area, physical_offsets); -} - -void CefPrintViewManagerBase::OnDidPrintDocument( - content::RenderFrameHost* render_frame_host, - const PrintHostMsg_DidPrintDocument_Params& params) { - if (!PrintJobHasDocument(params.document_cookie)) - return; - - const PrintHostMsg_DidPrintContent_Params& content = params.content; - if (!content.metafile_data_region.IsValid()) { - NOTREACHED() << "invalid memory handle"; - web_contents()->Stop(); - return; - } - - auto* client = PrintCompositeClient::FromWebContents(web_contents()); - if (IsOopifEnabled() && print_job_->document()->settings().is_modifiable()) { - client->DoCompositeDocumentToPdf( - params.document_cookie, render_frame_host, content, - base::BindOnce(&CefPrintViewManagerBase::OnComposePdfDone, - weak_ptr_factory_.GetWeakPtr(), params.page_size, - params.content_area, params.physical_offsets)); - return; - } - auto data = base::RefCountedSharedMemoryMapping::CreateFromWholeRegion( - content.metafile_data_region); - if (!data) { - NOTREACHED() << "couldn't map"; - web_contents()->Stop(); - return; - } - - PrintDocument(data, params.page_size, params.content_area, - params.physical_offsets); -} - -void CefPrintViewManagerBase::OnPrintingFailed(int cookie) { - PrintManager::OnPrintingFailed(cookie); - - ReleasePrinterQuery(); - - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_PRINT_JOB_RELEASED, - content::Source(web_contents()), - content::NotificationService::NoDetails()); -} - -void CefPrintViewManagerBase::OnShowInvalidPrinterSettingsError() {} - -void CefPrintViewManagerBase::DidStartLoading() { - UpdatePrintingEnabled(); -} - -void CefPrintViewManagerBase::RenderFrameDeleted( - content::RenderFrameHost* render_frame_host) { - // Terminates or cancels the print job if one was pending. - if (render_frame_host != printing_rfh_) - return; - - printing_rfh_ = nullptr; - - PrintManager::PrintingRenderFrameDeleted(); - ReleasePrinterQuery(); - - if (!print_job_) - return; - - scoped_refptr document(print_job_->document()); - if (document) { - // If IsComplete() returns false, the document isn't completely rendered. - // Since our renderer is gone, there's nothing to do, cancel it. Otherwise, - // the print job may finish without problem. - TerminatePrintJob(!document->IsComplete()); - } -} - -bool CefPrintViewManagerBase::OnMessageReceived( - const IPC::Message& message, - content::RenderFrameHost* render_frame_host) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(CefPrintViewManagerBase, message, - render_frame_host) - IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintDocument, OnDidPrintDocument) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - if (handled) - return true; - - handled = true; - IPC_BEGIN_MESSAGE_MAP(CefPrintViewManagerBase, message) - IPC_MESSAGE_HANDLER(PrintHostMsg_ShowInvalidPrinterSettingsError, - OnShowInvalidPrinterSettingsError) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled || PrintManager::OnMessageReceived(message, render_frame_host); -} - -void CefPrintViewManagerBase::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - DCHECK_EQ(chrome::NOTIFICATION_PRINT_JOB_EVENT, type); - OnNotifyPrintJobEvent(*content::Details(details).ptr()); -} - -void CefPrintViewManagerBase::OnNotifyPrintJobEvent( - const JobEventDetails& event_details) { - switch (event_details.type()) { - case JobEventDetails::FAILED: { - TerminatePrintJob(true); - - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_PRINT_JOB_RELEASED, - content::Source(web_contents()), - content::NotificationService::NoDetails()); - break; - } - case JobEventDetails::USER_INIT_DONE: - case JobEventDetails::DEFAULT_INIT_DONE: - case JobEventDetails::USER_INIT_CANCELED: { - NOTREACHED(); - break; - } - case JobEventDetails::ALL_PAGES_REQUESTED: { - ShouldQuitFromInnerMessageLoop(); - break; - } -#if defined(OS_WIN) - case JobEventDetails::PAGE_DONE: -#endif - case JobEventDetails::NEW_DOC: { - // Don't care about the actual printing process. - break; - } - case JobEventDetails::DOC_DONE: { - // Don't care about the actual printing process. - break; - } - case JobEventDetails::JOB_DONE: { - // Printing is done, we don't need it anymore. - // print_job_->is_job_pending() may still be true, depending on the order - // of object registration. - printing_succeeded_ = true; - ReleasePrintJob(); - - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_PRINT_JOB_RELEASED, - content::Source(web_contents()), - content::NotificationService::NoDetails()); - break; - } - default: { - NOTREACHED(); - break; - } - } -} - -bool CefPrintViewManagerBase::RenderAllMissingPagesNow() { - if (!print_job_ || !print_job_->is_job_pending()) - return false; - - // Is the document already complete? - if (print_job_->document() && print_job_->document()->IsComplete()) { - printing_succeeded_ = true; - return true; - } - - // We can't print if there is no renderer. - if (!web_contents() || !web_contents()->GetRenderViewHost() || - !web_contents()->GetRenderViewHost()->IsRenderViewLive()) { - return false; - } - - // WebContents is either dying or a second consecutive request to print - // happened before the first had time to finish. We need to render all the - // pages in an hurry if a print_job_ is still pending. No need to wait for it - // to actually spool the pages, only to have the renderer generate them. Run - // a message loop until we get our signal that the print job is satisfied. - // PrintJob will send a ALL_PAGES_REQUESTED after having received all the - // pages it needs. RunLoop::QuitCurrentWhenIdleDeprecated() will be called as - // soon as print_job_->document()->IsComplete() is true on either - // ALL_PAGES_REQUESTED or in DidPrintDocument(). The check is done in - // ShouldQuitFromInnerMessageLoop(). - // BLOCKS until all the pages are received. (Need to enable recursive task) - if (!RunInnerMessageLoop()) { - // This function is always called from DisconnectFromCurrentPrintJob() so we - // know that the job will be stopped/canceled in any case. - return false; - } - return true; -} - -void CefPrintViewManagerBase::ShouldQuitFromInnerMessageLoop() { - // Look at the reason. - DCHECK(print_job_->document()); - if (print_job_->document() && print_job_->document()->IsComplete() && - inside_inner_message_loop_) { - // We are in a message loop created by RenderAllMissingPagesNow. Quit from - // it. - base::RunLoop::QuitCurrentWhenIdleDeprecated(); - inside_inner_message_loop_ = false; - } -} - -bool CefPrintViewManagerBase::CreateNewPrintJob(PrinterQuery* query) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(!inside_inner_message_loop_); - DCHECK(query); - - // Disconnect the current |print_job_|. - DisconnectFromCurrentPrintJob(); - - // We can't print if there is no renderer. - if (!web_contents()->GetRenderViewHost() || - !web_contents()->GetRenderViewHost()->IsRenderViewLive()) { - return false; - } - - DCHECK(!print_job_); - print_job_ = base::MakeRefCounted(); - print_job_->Initialize(query, RenderSourceName(), number_pages_); - registrar_.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT, - content::Source(print_job_.get())); - printing_succeeded_ = false; - return true; -} - -void CefPrintViewManagerBase::DisconnectFromCurrentPrintJob() { - // Make sure all the necessary rendered page are done. Don't bother with the - // return value. - bool result = RenderAllMissingPagesNow(); - - // Verify that assertion. - if (print_job_ && print_job_->document() && - !print_job_->document()->IsComplete()) { - DCHECK(!result); - // That failed. - TerminatePrintJob(true); - } else { - // DO NOT wait for the job to finish. - ReleasePrintJob(); - } -} - -void CefPrintViewManagerBase::TerminatePrintJob(bool cancel) { - if (!print_job_) - return; - - if (cancel) { - // We don't need the metafile data anymore because the printing is canceled. - print_job_->Cancel(); - inside_inner_message_loop_ = false; - } else { - DCHECK(!inside_inner_message_loop_); - DCHECK(!print_job_->document() || print_job_->document()->IsComplete()); - - // WebContents is either dying or navigating elsewhere. We need to render - // all the pages in an hurry if a print job is still pending. This does the - // trick since it runs a blocking message loop: - print_job_->Stop(); - } - ReleasePrintJob(); -} - -void CefPrintViewManagerBase::ReleasePrintJob() { - content::RenderFrameHost* rfh = printing_rfh_; - printing_rfh_ = nullptr; - - if (!print_job_) - return; - - if (rfh) { - auto msg = std::make_unique(rfh->GetRoutingID(), - printing_succeeded_); - rfh->Send(msg.release()); - } - - registrar_.Remove(this, chrome::NOTIFICATION_PRINT_JOB_EVENT, - content::Source(print_job_.get())); - // Don't close the worker thread. - print_job_ = nullptr; -} - -bool CefPrintViewManagerBase::RunInnerMessageLoop() { - // This value may actually be too low: - // - // - If we're looping because of printer settings initialization, the premise - // here is that some poor users have their print server away on a VPN over a - // slow connection. In this situation, the simple fact of opening the printer - // can be dead slow. On the other side, we don't want to die infinitely for a - // real network error. Give the printer 60 seconds to comply. - // - // - If we're looping because of renderer page generation, the renderer could - // be CPU bound, the page overly complex/large or the system just - // memory-bound. - static constexpr base::TimeDelta kPrinterSettingsTimeout = - base::TimeDelta::FromSeconds(60); - base::OneShotTimer quit_timer; - base::RunLoop run_loop; - quit_timer.Start(FROM_HERE, kPrinterSettingsTimeout, - run_loop.QuitWhenIdleClosure()); - - inside_inner_message_loop_ = true; - - // Need to enable recursive task. - { - base::MessageLoopCurrent::ScopedNestableTaskAllower allow; - run_loop.Run(); - } - - bool success = true; - if (inside_inner_message_loop_) { - // Ok we timed out. That's sad. - inside_inner_message_loop_ = false; - success = false; - } - - return success; -} - -bool CefPrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) { - if (print_job_) - return true; - - if (!cookie) { - // Out of sync. It may happens since we are completely asynchronous. Old - // spurious message can happen if one of the processes is overloaded. - return false; - } - - // The job was initiated by a script. Time to get the corresponding worker - // thread. - scoped_refptr queued_query = queue_->PopPrinterQuery(cookie); - if (!queued_query) { - NOTREACHED(); - return false; - } - - if (!CreateNewPrintJob(queued_query.get())) { - // Don't kill anything. - return false; - } - - // Settings are already loaded. Go ahead. This will set - // print_job_->is_job_pending() to true. - print_job_->StartPrinting(); - return true; -} - -bool CefPrintViewManagerBase::PrintNowInternal( - content::RenderFrameHost* rfh, - std::unique_ptr message) { - // Don't print / print preview interstitials or crashed tabs. - if (web_contents()->ShowingInterstitialPage() || web_contents()->IsCrashed()) - return false; - return rfh->Send(message.release()); -} - -void CefPrintViewManagerBase::SetPrintingRFH(content::RenderFrameHost* rfh) { - DCHECK(!printing_rfh_); - printing_rfh_ = rfh; -} - -void CefPrintViewManagerBase::ReleasePrinterQuery() { - if (!cookie_) - return; - - int cookie = cookie_; - cookie_ = 0; - - PrintJobManager* print_job_manager = g_browser_process->print_job_manager(); - // May be NULL in tests. - if (!print_job_manager) - return; - - scoped_refptr printer_query; - printer_query = queue_->PopPrinterQuery(cookie); - if (!printer_query) - return; - base::PostTaskWithTraits( - FROM_HERE, {content::BrowserThread::IO}, - base::BindOnce(&PrinterQuery::StopWorker, printer_query)); -} - -void CefPrintViewManagerBase::SendPrintingEnabled( - bool enabled, - content::RenderFrameHost* rfh) { - rfh->Send(new PrintMsg_SetPrintingEnabled(rfh->GetRoutingID(), enabled)); -} - -} // namespace printing diff --git a/libcef/browser/printing/print_view_manager_base.h b/libcef/browser/printing/print_view_manager_base.h deleted file mode 100644 index 786d7c8b6..000000000 --- a/libcef/browser/printing/print_view_manager_base.h +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright 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. - -#ifndef CEF_LIBCEF_BROWSER_PRINTING_PRINT_VIEW_MANAGER_BASE_H_ -#define CEF_LIBCEF_BROWSER_PRINTING_PRINT_VIEW_MANAGER_BASE_H_ - -#include - -#include "base/macros.h" -#include "base/memory/read_only_shared_memory_region.h" -#include "base/memory/scoped_refptr.h" -#include "base/memory/weak_ptr.h" -#include "base/strings/string16.h" -#include "build/build_config.h" -#include "components/prefs/pref_member.h" -#include "components/printing/browser/print_manager.h" -#include "components/services/pdf_compositor/public/interfaces/pdf_compositor.mojom.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" -#include "mojo/public/cpp/system/platform_handle.h" -#include "printing/buildflags/buildflags.h" - -struct PrintHostMsg_DidPrintDocument_Params; - -namespace base { -class RefCountedMemory; -} - -namespace content { -class RenderFrameHost; -} - -namespace printing { - -class JobEventDetails; -class PrintJob; -class PrintQueriesQueue; -class PrinterQuery; - -// Base class for managing the print commands for a WebContents. -class CefPrintViewManagerBase : public content::NotificationObserver, - public PrintManager { - public: - ~CefPrintViewManagerBase() override; - - // Prints the current document immediately. Since the rendering is - // asynchronous, the actual printing will not be completed on the return of - // this function. Returns false if printing is impossible at the moment. - virtual bool PrintNow(content::RenderFrameHost* rfh); - - // Whether printing is enabled or not. - void UpdatePrintingEnabled(); - - base::string16 RenderSourceName(); - - protected: - explicit CefPrintViewManagerBase(content::WebContents* web_contents); - - // Helper method for Print*Now(). - bool PrintNowInternal(content::RenderFrameHost* rfh, - std::unique_ptr message); - - void SetPrintingRFH(content::RenderFrameHost* rfh); - - // content::WebContentsObserver implementation. - void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override; - bool OnMessageReceived(const IPC::Message& message, - content::RenderFrameHost* render_frame_host) override; - - // Cancels the print job. - void NavigationStopped() override; - - // Creates a new empty print job. It has no settings loaded. If there is - // currently a print job, safely disconnect from it. Returns false if it is - // impossible to safely disconnect from the current print job or it is - // impossible to create a new print job. - virtual bool CreateNewPrintJob(PrinterQuery* query); - - // Manages the low-level talk to the printer. - scoped_refptr print_job_; - - private: - // content::NotificationObserver implementation. - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; - - // content::WebContentsObserver implementation. - void DidStartLoading() override; - - // IPC Message handlers. - void OnDidGetPrintedPagesCount(int cookie, int number_pages) override; - void OnPrintingFailed(int cookie) override; - void OnShowInvalidPrinterSettingsError(); - void OnDidPrintDocument(content::RenderFrameHost* render_frame_host, - const PrintHostMsg_DidPrintDocument_Params& params); - - // IPC message handlers for service. - void OnComposePdfDone(const gfx::Size& page_size, - const gfx::Rect& content_area, - const gfx::Point& physical_offsets, - mojom::PdfCompositor::Status status, - base::ReadOnlySharedMemoryRegion region); - - // Processes a NOTIFY_PRINT_JOB_EVENT notification. - void OnNotifyPrintJobEvent(const JobEventDetails& event_details); - - // Requests the RenderView to render all the missing pages for the print job. - // No-op if no print job is pending. Returns true if at least one page has - // been requested to the renderer. - bool RenderAllMissingPagesNow(); - - // Checks that synchronization is correct with |print_job_| based on |cookie|. - bool PrintJobHasDocument(int cookie); - - // Starts printing the |document| in |print_job_| with the given |print_data|. - // This method assumes PrintJobHasDocument() has been called, and |print_data| - // contains valid data. - void PrintDocument(const scoped_refptr& print_data, - const gfx::Size& page_size, - const gfx::Rect& content_area, - const gfx::Point& offsets); - - // Quits the current message loop if these conditions hold true: a document is - // loaded and is complete and waiting_for_pages_to_be_rendered_ is true. This - // function is called in DidPrintDocument() or on ALL_PAGES_REQUESTED - // notification. The inner message loop is created was created by - // RenderAllMissingPagesNow(). - void ShouldQuitFromInnerMessageLoop(); - - // Makes sure the current print_job_ has all its data before continuing, and - // disconnect from it. - void DisconnectFromCurrentPrintJob(); - - // Terminates the print job. No-op if no print job has been created. If - // |cancel| is true, cancel it instead of waiting for the job to finish. Will - // call ReleasePrintJob(). - void TerminatePrintJob(bool cancel); - - // Releases print_job_. Correctly deregisters from notifications. No-op if - // no print job has been created. - void ReleasePrintJob(); - - // Runs an inner message loop. It will set inside_inner_message_loop_ to true - // while the blocking inner message loop is running. This is useful in cases - // where the RenderView is about to be destroyed while a printing job isn't - // finished. - bool RunInnerMessageLoop(); - - // In the case of Scripted Printing, where the renderer is controlling the - // control flow, print_job_ is initialized whenever possible. No-op is - // print_job_ is initialized. - bool OpportunisticallyCreatePrintJob(int cookie); - - // Release the PrinterQuery associated with our |cookie_|. - void ReleasePrinterQuery(); - - // Helper method for UpdatePrintingEnabled(). - void SendPrintingEnabled(bool enabled, content::RenderFrameHost* rfh); - - content::NotificationRegistrar registrar_; - - // The current RFH that is printing with a system printing dialog. - content::RenderFrameHost* printing_rfh_; - - // Indication of success of the print job. - bool printing_succeeded_; - - // Running an inner message loop inside RenderAllMissingPagesNow(). This means - // we are _blocking_ until all the necessary pages have been rendered or the - // print settings are being loaded. - bool inside_inner_message_loop_; - - // Whether printing is enabled. - BooleanPrefMember printing_enabled_; - - scoped_refptr queue_; - - base::WeakPtrFactory weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(CefPrintViewManagerBase); -}; - -} // namespace printing - -#endif // CEF_LIBCEF_BROWSER_PRINTING_PRINT_VIEW_MANAGER_BASE_H_ diff --git a/libcef/browser/views/browser_platform_delegate_views.cc b/libcef/browser/views/browser_platform_delegate_views.cc index 69c5bf34c..65128d3a1 100644 --- a/libcef/browser/views/browser_platform_delegate_views.cc +++ b/libcef/browser/views/browser_platform_delegate_views.cc @@ -52,18 +52,23 @@ class PopupWindowDelegate : public CefWindowDelegate { CefBrowserPlatformDelegateViews::CefBrowserPlatformDelegateViews( std::unique_ptr native_delegate, CefRefPtr browser_view) - : native_delegate_(std::move(native_delegate)), - browser_view_(browser_view) { + : native_delegate_(std::move(native_delegate)) { + if (browser_view) + SetBrowserView(browser_view); native_delegate_->set_windowless_handler(this); } -void CefBrowserPlatformDelegateViews::set_browser_view( +void CefBrowserPlatformDelegateViews::SetBrowserView( CefRefPtr browser_view) { + DCHECK(!browser_view_); + DCHECK(browser_view); browser_view_ = browser_view; } void CefBrowserPlatformDelegateViews::WebContentsCreated( content::WebContents* web_contents) { + CefBrowserPlatformDelegate::WebContentsCreated(web_contents); + browser_view_->WebContentsCreated(web_contents); } @@ -71,7 +76,7 @@ void CefBrowserPlatformDelegateViews::BrowserCreated( CefBrowserHostImpl* browser) { CefBrowserPlatformDelegate::BrowserCreated(browser); - browser_view_->BrowserCreated(browser); + browser_view_->BrowserCreated(browser, GetBoundsChangedCallback()); } void CefBrowserPlatformDelegateViews::NotifyBrowserCreated() { @@ -143,7 +148,7 @@ void CefBrowserPlatformDelegateViews::PopupWebContentsCreated( CefBrowserViewImpl::CreateForPopup(settings, new_delegate); // Associate the PlatformDelegate with the new BrowserView. - new_platform_delegate_impl->set_browser_view(new_browser_view); + new_platform_delegate_impl->SetBrowserView(new_browser_view); } void CefBrowserPlatformDelegateViews::PopupBrowserCreated( @@ -293,6 +298,23 @@ bool CefBrowserPlatformDelegateViews::IsViewsHosted() const { return true; } +gfx::Point CefBrowserPlatformDelegateViews::GetDialogPosition( + const gfx::Size& size) { + const gfx::Rect& bounds = browser_view_->root_view()->GetBoundsInScreen(); + + // Offset relative to the top-level content view. + gfx::Point offset = bounds.origin(); + view_util::ConvertPointFromScreen( + browser_view_->root_view()->GetWidget()->GetRootView(), &offset, false); + + return gfx::Point(offset.x() + (bounds.width() - size.width()) / 2, + offset.y() + (bounds.height() - size.height()) / 2); +} + +gfx::Size CefBrowserPlatformDelegateViews::GetMaximumDialogSize() { + return browser_view_->root_view()->GetBoundsInScreen().size(); +} + CefWindowHandle CefBrowserPlatformDelegateViews::GetParentWindowHandle() const { return GetHostWindowHandle(); } diff --git a/libcef/browser/views/browser_platform_delegate_views.h b/libcef/browser/views/browser_platform_delegate_views.h index 0b622b4a7..f452b39a8 100644 --- a/libcef/browser/views/browser_platform_delegate_views.h +++ b/libcef/browser/views/browser_platform_delegate_views.h @@ -20,8 +20,6 @@ class CefBrowserPlatformDelegateViews std::unique_ptr native_delegate, CefRefPtr browser_view); - void set_browser_view(CefRefPtr browser_view); - // CefBrowserPlatformDelegate methods: void WebContentsCreated(content::WebContents* web_contents) override; void BrowserCreated(CefBrowserHostImpl* browser) override; @@ -76,12 +74,16 @@ class CefBrowserPlatformDelegateViews std::unique_ptr CreateMenuRunner() override; bool IsWindowless() const override; bool IsViewsHosted() const override; + gfx::Point GetDialogPosition(const gfx::Size& size) override; + gfx::Size GetMaximumDialogSize() override; // CefBrowserPlatformDelegateNative::WindowlessHandler methods: CefWindowHandle GetParentWindowHandle() const override; gfx::Point GetParentScreenPoint(const gfx::Point& view) const override; private: + void SetBrowserView(CefRefPtr browser_view); + std::unique_ptr native_delegate_; CefRefPtr browser_view_; }; diff --git a/libcef/browser/views/browser_view_impl.cc b/libcef/browser/views/browser_view_impl.cc index 2ca65a208..deebcc305 100644 --- a/libcef/browser/views/browser_view_impl.cc +++ b/libcef/browser/views/browser_view_impl.cc @@ -70,8 +70,11 @@ void CefBrowserViewImpl::WebContentsCreated( root_view()->SetWebContents(web_contents); } -void CefBrowserViewImpl::BrowserCreated(CefBrowserHostImpl* browser) { +void CefBrowserViewImpl::BrowserCreated( + CefBrowserHostImpl* browser, + base::RepeatingClosure on_bounds_changed) { browser_ = browser; + on_bounds_changed_ = on_bounds_changed; } void CefBrowserViewImpl::BrowserDestroyed(CefBrowserHostImpl* browser) { @@ -165,6 +168,11 @@ void CefBrowserViewImpl::OnBrowserViewAdded() { } } +void CefBrowserViewImpl::OnBoundsChanged() { + if (!on_bounds_changed_.is_null()) + on_bounds_changed_.Run(); +} + CefBrowserViewImpl::CefBrowserViewImpl( CefRefPtr delegate) : ParentClass(delegate) {} diff --git a/libcef/browser/views/browser_view_impl.h b/libcef/browser/views/browser_view_impl.h index 639a9ac10..f35e647af 100644 --- a/libcef/browser/views/browser_view_impl.h +++ b/libcef/browser/views/browser_view_impl.h @@ -14,6 +14,7 @@ #include "libcef/browser/views/browser_view_view.h" #include "libcef/browser/views/view_impl.h" +#include "base/callback_forward.h" #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h" class CefBrowserViewImpl : public CefViewImplOnBrowserViewAdded(); } } + +void CefBrowserViewView::OnBoundsChanged(const gfx::Rect& previous_bounds) { + ParentClass::OnBoundsChanged(previous_bounds); + browser_view_delegate_->OnBoundsChanged(); +} diff --git a/libcef/browser/views/browser_view_view.h b/libcef/browser/views/browser_view_view.h index 32c09bb74..7a50d8afb 100644 --- a/libcef/browser/views/browser_view_view.h +++ b/libcef/browser/views/browser_view_view.h @@ -29,6 +29,9 @@ class CefBrowserViewView // Called when the BrowserView has been added to a parent view. virtual void OnBrowserViewAdded() = 0; + // Called when the BrowserView bounds have changed. + virtual void OnBoundsChanged() = 0; + protected: virtual ~Delegate() {} }; @@ -41,6 +44,7 @@ class CefBrowserViewView // View methods: void ViewHierarchyChanged( const views::ViewHierarchyChangedDetails& details) override; + void OnBoundsChanged(const gfx::Rect& previous_bounds) override; private: // Not owned by this object. diff --git a/libcef/browser/web_contents_dialog_helper.cc b/libcef/browser/web_contents_dialog_helper.cc new file mode 100644 index 000000000..ffabe5d7c --- /dev/null +++ b/libcef/browser/web_contents_dialog_helper.cc @@ -0,0 +1,72 @@ +// Copyright (c) 2019 The Chromium Embedded Framework 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/web_contents_dialog_helper.h" + +#include "libcef/browser/browser_platform_delegate.h" + +#include "chrome/browser/platform_util.h" +#include "components/web_modal/web_contents_modal_dialog_manager.h" + +#if defined(USE_AURA) +#include "ui/views/widget/widget.h" +#endif + +CefWebContentsDialogHelper::CefWebContentsDialogHelper( + content::WebContents* web_contents, + CefBrowserPlatformDelegate* browser_delegate) + : browser_delegate_(browser_delegate), weak_factory_(this) { + web_modal::WebContentsModalDialogManager::CreateForWebContents(web_contents); + web_modal::WebContentsModalDialogManager::FromWebContents(web_contents) + ->SetDelegate(this); +} + +base::RepeatingClosure CefWebContentsDialogHelper::GetBoundsChangedCallback() { + return base::BindRepeating(&CefWebContentsDialogHelper::OnBoundsChanged, + weak_factory_.GetWeakPtr()); +} + +bool CefWebContentsDialogHelper::IsWebContentsVisible( + content::WebContents* web_contents) { + return platform_util::IsVisible(web_contents->GetNativeView()); +} + +web_modal::WebContentsModalDialogHost* +CefWebContentsDialogHelper::GetWebContentsModalDialogHost() { + return this; +} + +gfx::NativeView CefWebContentsDialogHelper::GetHostView() const { +#if defined(USE_AURA) + return browser_delegate_->GetWindowWidget()->GetNativeView(); +#else + NOTIMPLEMENTED(); + return gfx::NativeView(); +#endif +} + +gfx::Point CefWebContentsDialogHelper::GetDialogPosition( + const gfx::Size& size) { + return browser_delegate_->GetDialogPosition(size); +} + +gfx::Size CefWebContentsDialogHelper::GetMaximumDialogSize() { + return browser_delegate_->GetMaximumDialogSize(); +} + +void CefWebContentsDialogHelper::AddObserver( + web_modal::ModalDialogHostObserver* observer) { + if (observer && !observer_list_.HasObserver(observer)) + observer_list_.AddObserver(observer); +} + +void CefWebContentsDialogHelper::RemoveObserver( + web_modal::ModalDialogHostObserver* observer) { + observer_list_.RemoveObserver(observer); +} + +void CefWebContentsDialogHelper::OnBoundsChanged() { + for (auto& observer : observer_list_) + observer.OnPositionRequiresUpdate(); +} diff --git a/libcef/browser/web_contents_dialog_helper.h b/libcef/browser/web_contents_dialog_helper.h new file mode 100644 index 000000000..39be126bf --- /dev/null +++ b/libcef/browser/web_contents_dialog_helper.h @@ -0,0 +1,51 @@ +// Copyright (c) 2019 The Chromium Embedded Framework 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_WEB_CONTENTS_DIALOG_HELPER_H_ +#define CEF_LIBCEF_BROWSER_WEB_CONTENTS_DIALOG_HELPER_H_ +#pragma once + +#include "base/callback_forward.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "components/web_modal/modal_dialog_host.h" +#include "components/web_modal/web_contents_modal_dialog_host.h" +#include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" + +class CefBrowserPlatformDelegate; + +class CefWebContentsDialogHelper + : public web_modal::WebContentsModalDialogManagerDelegate, + public web_modal::WebContentsModalDialogHost { + public: + CefWebContentsDialogHelper(content::WebContents* web_contents, + CefBrowserPlatformDelegate* browser_delegate); + + base::RepeatingClosure GetBoundsChangedCallback(); + + // web_modal::WebContentsModalDialogManagerDelegate methods: + bool IsWebContentsVisible(content::WebContents* web_contents) override; + web_modal::WebContentsModalDialogHost* GetWebContentsModalDialogHost() + override; + + // web_modal::WebContentsModalDialogHost methods: + gfx::NativeView GetHostView() const override; + gfx::Point GetDialogPosition(const gfx::Size& size) override; + gfx::Size GetMaximumDialogSize() override; + void AddObserver(web_modal::ModalDialogHostObserver* observer) override; + void RemoveObserver(web_modal::ModalDialogHostObserver* observer) override; + + private: + void OnBoundsChanged(); + + CefBrowserPlatformDelegate* const browser_delegate_; + + // Used to notify WebContentsModalDialog. + base::ObserverList::Unchecked + observer_list_; + + base::WeakPtrFactory weak_factory_; +}; + +#endif // CEF_LIBCEF_BROWSER_WEB_CONTENTS_DIALOG_HELPER_H_ diff --git a/libcef/common/cef_switches.cc b/libcef/common/cef_switches.cc index 520abcd25..4cfe8ff60 100644 --- a/libcef/common/cef_switches.cc +++ b/libcef/common/cef_switches.cc @@ -116,6 +116,9 @@ const char kEnablePreferenceTesting[] = "enable-preference-testing"; // Enable date-based expiration of built in network security information. const char kEnableNetSecurityExpiration[] = "enable-net-security-expiration"; +// Enable print preview. +extern const char kEnablePrintPreview[] = "enable-print-preview"; + #if defined(OS_MACOSX) // Path to the framework directory. const char kFrameworkDirPath[] = "framework-dir-path"; diff --git a/libcef/common/cef_switches.h b/libcef/common/cef_switches.h index ea00cd841..93d5a58f2 100644 --- a/libcef/common/cef_switches.h +++ b/libcef/common/cef_switches.h @@ -52,6 +52,7 @@ extern const char kPluginPolicy_Detect[]; extern const char kPluginPolicy_Block[]; extern const char kEnablePreferenceTesting[]; extern const char kEnableNetSecurityExpiration[]; +extern const char kEnablePrintPreview[]; #if defined(OS_MACOSX) extern const char kFrameworkDirPath[]; diff --git a/libcef/common/extensions/extensions_util.cc b/libcef/common/extensions/extensions_util.cc index a1ba43e11..74f0ad8f0 100644 --- a/libcef/common/extensions/extensions_util.cc +++ b/libcef/common/extensions/extensions_util.cc @@ -24,4 +24,22 @@ bool PdfExtensionEnabled() { return enabled; } +bool PrintPreviewEnabled() { +#if defined(OS_MACOSX) + // Not currently supported on macOS. + return false; +#else + if (!PdfExtensionEnabled()) + return false; + + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisablePrintPreview)) { + return false; + } + + return base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnablePrintPreview); +#endif +} + } // namespace extensions diff --git a/libcef/common/extensions/extensions_util.h b/libcef/common/extensions/extensions_util.h index 2dd8dc939..6bcbdde7a 100644 --- a/libcef/common/extensions/extensions_util.h +++ b/libcef/common/extensions/extensions_util.h @@ -13,6 +13,9 @@ bool ExtensionsEnabled(); // Returns true if the PDF extension has not been disabled via the command-line. bool PdfExtensionEnabled(); +// Returns true if Print Preview has been enabled via the command-line. +bool PrintPreviewEnabled(); + } // namespace extensions #endif // CEF_LIBCEF_COMMON_EXTENSIONS_EXTENSIONS_UTIL_H_ diff --git a/libcef/common/main_delegate.cc b/libcef/common/main_delegate.cc index 3cc1b2b70..64435666f 100644 --- a/libcef/common/main_delegate.cc +++ b/libcef/common/main_delegate.cc @@ -33,6 +33,7 @@ #include "chrome/child/pdf_child_init.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths.h" +#include "chrome/common/chrome_paths_internal.h" #include "chrome/common/chrome_switches.h" #include "components/content_settings/core/common/content_settings_pattern.h" #include "components/viz/common/features.h" @@ -254,6 +255,26 @@ base::FilePath GetUserDataPath() { return result; } +bool GetDefaultDownloadDirectory(base::FilePath* result) { + base::FilePath cur; + if (!chrome::GetUserDownloadsDirectory(&cur)) + return false; + *result = cur; + return true; +} + +bool GetDefaultDownloadSafeDirectory(base::FilePath* result) { + base::FilePath cur; +#if defined(OS_WIN) || defined(OS_LINUX) + if (!chrome::GetUserDownloadsDirectorySafe(&cur)) + return false; +#else + GetDefaultDownloadDirectory(&cur); +#endif + *result = cur; + return true; +} + // Returns true if |scale_factor| is supported by this platform. // Same as ui::ResourceBundle::IsScaleFactorSupported. bool IsScaleFactorSupported(ui::ScaleFactor scale_factor) { @@ -662,6 +683,17 @@ void CefMainDelegate::PreSandboxStartup() { OverridePepperFlashSystemPluginPath(); + base::FilePath dir_default_download; + base::FilePath dir_default_download_safe; + if (GetDefaultDownloadDirectory(&dir_default_download)) { + base::PathService::Override(chrome::DIR_DEFAULT_DOWNLOADS, + dir_default_download); + } + if (GetDefaultDownloadSafeDirectory(&dir_default_download_safe)) { + base::PathService::Override(chrome::DIR_DEFAULT_DOWNLOADS_SAFE, + dir_default_download_safe); + } + const base::FilePath& user_data_path = GetUserDataPath(); base::PathService::Override(chrome::DIR_USER_DATA, user_data_path); diff --git a/libcef/renderer/content_renderer_client.cc b/libcef/renderer/content_renderer_client.cc index 11375ef7c..72fc11290 100644 --- a/libcef/renderer/content_renderer_client.cc +++ b/libcef/renderer/content_renderer_client.cc @@ -468,9 +468,6 @@ void CefContentRendererClient::RenderFrameCreated( service_manager::BinderRegistry* registry = render_frame_observer->registry(); new PepperHelper(render_frame); - new printing::PrintRenderFrameHelper( - render_frame, - base::WrapUnique(new extensions::CefPrintRenderFrameHelperDelegate())); if (extensions::ExtensionsEnabled()) extensions_renderer_client_->RenderFrameCreated(render_frame, registry); @@ -670,6 +667,12 @@ CefRefPtr CefContentRendererClient::MaybeCreateBrowser( CefProcessHostMsg_GetNewBrowserInfo_Params params; content::RenderThread::Get()->Send(new CefProcessHostMsg_GetNewBrowserInfo( render_frame_routing_id, ¶ms)); + + new printing::PrintRenderFrameHelper( + render_frame, + base::WrapUnique(new extensions::CefPrintRenderFrameHelperDelegate( + params.is_windowless))); + if (params.browser_id == 0) { // The popup may have been canceled during creation. return nullptr; diff --git a/libcef/renderer/extensions/print_render_frame_helper_delegate.cc b/libcef/renderer/extensions/print_render_frame_helper_delegate.cc index ccfb59088..5e2a0e0dc 100644 --- a/libcef/renderer/extensions/print_render_frame_helper_delegate.cc +++ b/libcef/renderer/extensions/print_render_frame_helper_delegate.cc @@ -6,18 +6,27 @@ #include +#include "libcef/common/extensions/extensions_util.h" + +#include "base/command_line.h" +#include "base/strings/string_util.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension_constants.h" +#include "chrome/common/url_constants.h" #include "content/public/renderer/render_frame.h" -#include "content/public/renderer/render_view.h" #include "extensions/common/constants.h" #include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.h" +#include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_element.h" #include "third_party/blink/public/web/web_local_frame.h" namespace extensions { +CefPrintRenderFrameHelperDelegate::CefPrintRenderFrameHelperDelegate( + bool is_windowless) + : is_windowless_(is_windowless) {} + CefPrintRenderFrameHelperDelegate::~CefPrintRenderFrameHelperDelegate() {} bool CefPrintRenderFrameHelperDelegate::CancelPrerender( @@ -29,8 +38,11 @@ bool CefPrintRenderFrameHelperDelegate::CancelPrerender( blink::WebElement CefPrintRenderFrameHelperDelegate::GetPdfElement( blink::WebLocalFrame* frame) { GURL url = frame->GetDocument().Url(); - if (url.SchemeIs(extensions::kExtensionScheme) && - url.host() == extension_misc::kPdfExtensionId) { + bool inside_print_preview = url.GetOrigin() == chrome::kChromeUIPrintURL; + bool inside_pdf_extension = + url.SchemeIs(extensions::kExtensionScheme) && + url.host_piece() == extension_misc::kPdfExtensionId; + if (inside_print_preview || inside_pdf_extension) { // with id="plugin" is created in // chrome/browser/resources/pdf/pdf.js. auto plugin_element = frame->GetDocument().GetElementById("plugin"); @@ -43,7 +55,7 @@ blink::WebElement CefPrintRenderFrameHelperDelegate::GetPdfElement( } bool CefPrintRenderFrameHelperDelegate::IsPrintPreviewEnabled() { - return false; + return !is_windowless_ && PrintPreviewEnabled(); } bool CefPrintRenderFrameHelperDelegate::OverridePrint( diff --git a/libcef/renderer/extensions/print_render_frame_helper_delegate.h b/libcef/renderer/extensions/print_render_frame_helper_delegate.h index 3a4239b6e..58f9f5bf3 100644 --- a/libcef/renderer/extensions/print_render_frame_helper_delegate.h +++ b/libcef/renderer/extensions/print_render_frame_helper_delegate.h @@ -12,12 +12,16 @@ namespace extensions { class CefPrintRenderFrameHelperDelegate : public printing::PrintRenderFrameHelper::Delegate { public: + explicit CefPrintRenderFrameHelperDelegate(bool is_windowless); ~CefPrintRenderFrameHelperDelegate() override; bool CancelPrerender(content::RenderFrame* render_frame) override; blink::WebElement GetPdfElement(blink::WebLocalFrame* frame) override; bool IsPrintPreviewEnabled() override; bool OverridePrint(blink::WebLocalFrame* frame) override; + + private: + bool is_windowless_; }; } // namespace extensions diff --git a/patch/patch.cfg b/patch/patch.cfg index f82cf28b5..60fb6c889 100644 --- a/patch/patch.cfg +++ b/patch/patch.cfg @@ -144,19 +144,6 @@ patches = [ # https://bitbucket.org/chromiumembedded/cef/issue/1610 'name': 'ime_1610', }, - { - # Enable support for print header and footer. - # https://bitbucket.org/chromiumembedded/cef/issue/1478 - # - # Fix printing of PDF documents via PrintToPDF. - # https://bitbucket.org/chromiumembedded/cef/issues/1565 - # - # Revert ENABLE_PRINT_PREVIEW changes from the following changeset. - # https://codereview.chromium.org/1556463003 - # - # Add ENABLE_CEF checks in chrome/browser/ui. - 'name': 'print_header_footer_1478_1565', - }, { # Split service_manager::Main into the separate steps required by CEF. # https://bugs.chromium.org/p/chromium/issues/detail?id=654986#c17 @@ -468,5 +455,13 @@ patches = [ # Add support for OSR rendering with Viz. # https://bitbucket.org/chromiumembedded/cef/issues/2575 'name': 'viz_osr_2575', + }, + { + # Changes for print preview support: + # - Don't attach unnecessary Chrome-related handlers to constrained window. + # - Create file dialogs using the CEF code path. + # - Remove unsupported print preview UI options. + # https://bitbucket.org/chromiumembedded/cef/issues/123 + 'name': 'print_preview_123', } ] diff --git a/patch/patches/print_header_footer_1478_1565.patch b/patch/patches/print_header_footer_1478_1565.patch deleted file mode 100644 index 932e5fdaf..000000000 --- a/patch/patches/print_header_footer_1478_1565.patch +++ /dev/null @@ -1,573 +0,0 @@ -diff --git chrome/app/builtin_service_manifests.cc chrome/app/builtin_service_manifests.cc -index 6c9c779d785e..6032d42122d3 100644 ---- chrome/app/builtin_service_manifests.cc -+++ chrome/app/builtin_service_manifests.cc -@@ -10,6 +10,7 @@ - #include "chrome/common/constants.mojom.h" - #include "chrome/services/file_util/public/cpp/manifest.h" - #include "chrome/services/noop/public/cpp/manifest.h" -+#include "chrome/services/printing/public/cpp/manifest.h" - #include "components/services/patch/public/cpp/manifest.h" - #include "components/services/quarantine/public/cpp/manifest.h" - #include "components/services/unzip/public/cpp/manifest.h" -@@ -60,10 +61,6 @@ - #include "components/services/pdf_compositor/public/cpp/manifest.h" // nogncheck - #endif - --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) --#include "chrome/services/printing/public/cpp/manifest.h" --#endif -- - #if BUILDFLAG(ENABLE_ISOLATED_XR_SERVICE) - #include "chrome/services/isolated_xr_device/manifest.h" - #endif -diff --git chrome/app/printing_strings.grdp chrome/app/printing_strings.grdp -index c7533c13e863..7578f9b6ae71 100644 ---- chrome/app/printing_strings.grdp -+++ chrome/app/printing_strings.grdp -@@ -1,11 +1,9 @@ - - - -- - - Printing Service - -- - - - The selected printer is not available or not installed correctly. Check your printer or try selecting another printer. -diff --git chrome/browser/ui/cocoa/applescript/tab_applescript.mm chrome/browser/ui/cocoa/applescript/tab_applescript.mm -index d4c9283b3cef..4a91987bfe7f 100644 ---- chrome/browser/ui/cocoa/applescript/tab_applescript.mm -+++ chrome/browser/ui/cocoa/applescript/tab_applescript.mm -@@ -9,7 +9,7 @@ - #include "base/logging.h" - #import "base/mac/scoped_nsobject.h" - #include "base/strings/sys_string_conversions.h" --#include "chrome/browser/printing/print_view_manager.h" -+#include "cef/libcef/features/features.h" - #include "chrome/browser/profiles/profile.h" - #include "chrome/browser/sessions/session_tab_helper.h" - #include "chrome/browser/ui/cocoa/applescript/apple_event_util.h" -@@ -27,6 +27,10 @@ - #include "content/public/browser/web_contents_delegate.h" - #include "url/gurl.h" - -+#if !BUILDFLAG(ENABLE_CEF) -+#include "chrome/browser/printing/print_view_manager.h" -+#endif -+ - using content::NavigationController; - using content::NavigationEntry; - using content::OpenURLParams; -@@ -234,11 +238,15 @@ void ResumeAppleEventAndSendReply(NSAppleEventManagerSuspensionID suspension_id, - - - (void)handlesPrintScriptCommand:(NSScriptCommand*)command { - AppleScript::LogAppleScriptUMA(AppleScript::AppleScriptCommand::TAB_PRINT); -+#if !BUILDFLAG(ENABLE_CEF) - bool initiated = printing::PrintViewManager::FromWebContents(webContents_) - ->PrintNow(webContents_->GetMainFrame()); - if (!initiated) { - AppleScript::SetError(AppleScript::errInitiatePrinting); - } -+#else -+ NOTIMPLEMENTED(); -+#endif - } - - - (void)handlesSaveScriptCommand:(NSScriptCommand*)command { -diff --git chrome/browser/ui/webui/settings/printing_handler.cc chrome/browser/ui/webui/settings/printing_handler.cc -index 8647b2daf9ea..b070ab3e4b86 100644 ---- chrome/browser/ui/webui/settings/printing_handler.cc -+++ chrome/browser/ui/webui/settings/printing_handler.cc -@@ -6,9 +6,13 @@ - - #include "base/bind.h" - #include "base/bind_helpers.h" --#include "chrome/browser/printing/printer_manager_dialog.h" -+#include "cef/libcef/features/features.h" - #include "content/public/browser/web_ui.h" - -+#if !BUILDFLAG(ENABLE_CEF) -+#include "chrome/browser/printing/printer_manager_dialog.h" -+#endif -+ - namespace settings { - - PrintingHandler::PrintingHandler() {} -@@ -27,7 +31,11 @@ void PrintingHandler::OnJavascriptAllowed() {} - void PrintingHandler::OnJavascriptDisallowed() {} - - void PrintingHandler::HandleOpenSystemPrintDialog(const base::ListValue* args) { -+#if !BUILDFLAG(ENABLE_CEF) - printing::PrinterManagerDialog::ShowPrinterManagerDialog(); -+#else -+ NOTIMPLEMENTED(); -+#endif - } - - } // namespace settings -diff --git chrome/common/chrome_utility_printing_messages.h chrome/common/chrome_utility_printing_messages.h -index 6bd558079c97..6832bf9f297b 100644 ---- chrome/common/chrome_utility_printing_messages.h -+++ chrome/common/chrome_utility_printing_messages.h -@@ -16,7 +16,7 @@ - - #define IPC_MESSAGE_START ChromeUtilityPrintingMsgStart - --#if defined(OS_WIN) && BUILDFLAG(ENABLE_PRINT_PREVIEW) -+#if defined(OS_WIN) - // Preview and Cloud Print messages. - IPC_STRUCT_TRAITS_BEGIN(printing::PrinterCapsAndDefaults) - IPC_STRUCT_TRAITS_MEMBER(printer_capabilities) -@@ -94,6 +94,6 @@ IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_GetPrinterCapsAndDefaults_Failed, - IPC_MESSAGE_CONTROL1( - ChromeUtilityHostMsg_GetPrinterSemanticCapsAndDefaults_Failed, - std::string /* printer name */) --#endif // defined(OS_WIN) && BUILDFLAG(ENABLE_PRINT_PREVIEW) -+#endif // defined(OS_WIN) - - #endif // CHROME_COMMON_CHROME_UTILITY_PRINTING_MESSAGES_H_ -diff --git chrome/utility/printing_handler.h chrome/utility/printing_handler.h -index 006966fd1c58..db9cd49af2a4 100644 ---- chrome/utility/printing_handler.h -+++ chrome/utility/printing_handler.h -@@ -11,7 +11,7 @@ - #include "build/build_config.h" - #include "printing/buildflags/buildflags.h" - --#if !defined(OS_WIN) || !BUILDFLAG(ENABLE_PRINT_PREVIEW) -+#if !defined(OS_WIN) - #error "Windows printing and print preview must be enabled" - #endif - -diff --git components/printing/common/print_messages.cc components/printing/common/print_messages.cc -index 528773d80a2f..3355de3884cd 100644 ---- components/printing/common/print_messages.cc -+++ components/printing/common/print_messages.cc -@@ -131,7 +131,6 @@ PrintMsg_PrintFrame_Params::PrintMsg_PrintFrame_Params() {} - - PrintMsg_PrintFrame_Params::~PrintMsg_PrintFrame_Params() {} - --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - PrintHostMsg_RequestPrintPreview_Params:: - PrintHostMsg_RequestPrintPreview_Params() - : is_modifiable(false), -@@ -161,4 +160,3 @@ PrintHostMsg_SetOptionsFromDocument_Params:: - PrintHostMsg_SetOptionsFromDocument_Params:: - ~PrintHostMsg_SetOptionsFromDocument_Params() { - } --#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) -diff --git components/printing/common/print_messages.h components/printing/common/print_messages.h -index 1802034a6e15..ae0d479ecafa 100644 ---- components/printing/common/print_messages.h -+++ components/printing/common/print_messages.h -@@ -85,7 +85,6 @@ struct PrintMsg_PrintFrame_Params { - int document_cookie; - }; - --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - struct PrintHostMsg_RequestPrintPreview_Params { - PrintHostMsg_RequestPrintPreview_Params(); - ~PrintHostMsg_RequestPrintPreview_Params(); -@@ -112,7 +111,6 @@ struct PrintHostMsg_SetOptionsFromDocument_Params { - printing::DuplexMode duplex; - printing::PageRanges page_ranges; - }; --#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) - - #endif // INTERNAL_COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ - -@@ -211,7 +209,6 @@ IPC_STRUCT_TRAITS_BEGIN(printing::PageRange) - IPC_STRUCT_TRAITS_MEMBER(to) - IPC_STRUCT_TRAITS_END() - --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - IPC_STRUCT_TRAITS_BEGIN(PrintHostMsg_RequestPrintPreview_Params) - IPC_STRUCT_TRAITS_MEMBER(is_modifiable) - IPC_STRUCT_TRAITS_MEMBER(webnode_only) -@@ -237,7 +234,6 @@ IPC_STRUCT_TRAITS_BEGIN(PrintHostMsg_SetOptionsFromDocument_Params) - // Specifies page range to be printed. - IPC_STRUCT_TRAITS_MEMBER(page_ranges) - IPC_STRUCT_TRAITS_END() --#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) - - IPC_STRUCT_TRAITS_BEGIN(printing::PageSizeMargins) - IPC_STRUCT_TRAITS_MEMBER(content_width) -@@ -278,7 +274,6 @@ IPC_STRUCT_BEGIN(PrintHostMsg_DidPrintContent_Params) - IPC_STRUCT_MEMBER(printing::ContentToProxyIdMap, subframe_content_info) - IPC_STRUCT_END() - --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - // Parameters to describe the to-be-rendered preview document. - IPC_STRUCT_BEGIN(PrintHostMsg_DidStartPreview_Params) - // Total page count for the rendered preview. (Not the number of pages the -@@ -321,7 +316,6 @@ IPC_STRUCT_BEGIN(PrintHostMsg_DidPreviewDocument_Params) - // Store the expected pages count. - IPC_STRUCT_MEMBER(int, expected_pages_count) - IPC_STRUCT_END() --#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) - - // Parameters to describe a rendered page. - IPC_STRUCT_BEGIN(PrintHostMsg_DidPrintDocument_Params) -@@ -356,20 +350,18 @@ IPC_STRUCT_END() - - // Messages sent from the browser to the renderer. - --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - // Tells the RenderFrame to initiate print preview for the entire document. - IPC_MESSAGE_ROUTED1(PrintMsg_InitiatePrintPreview, bool /* has_selection */) --#endif - - // Tells the RenderFrame to initiate printing or print preview for a particular - // node, depending on which mode the RenderFrame is in. - IPC_MESSAGE_ROUTED0(PrintMsg_PrintNodeUnderContextMenu) - --#if BUILDFLAG(ENABLE_PRINTING) - // Tells the RenderFrame to switch the CSS to print media type, renders every - // requested pages and switch back the CSS to display media type. - IPC_MESSAGE_ROUTED0(PrintMsg_PrintPages) - -+#if BUILDFLAG(ENABLE_PRINTING) - // Like PrintMsg_PrintPages, but using the print preview document's frame/node. - IPC_MESSAGE_ROUTED0(PrintMsg_PrintForSystemDialog) - #endif -@@ -384,7 +376,6 @@ IPC_MESSAGE_ROUTED1(PrintMsg_PrintingDone, - // Tells the RenderFrame whether printing is enabled or not. - IPC_MESSAGE_ROUTED1(PrintMsg_SetPrintingEnabled, bool /* enabled */) - --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - // Tells the RenderFrame to switch the CSS to print media type, renders every - // requested pages for print preview using the given |settings|. This gets - // called multiple times as the user updates settings. -@@ -393,7 +384,6 @@ IPC_MESSAGE_ROUTED1(PrintMsg_PrintPreview, - - // Tells the RenderFrame that print preview dialog was closed. - IPC_MESSAGE_ROUTED0(PrintMsg_ClosePrintPreviewDialog) --#endif - - // Messages sent from the renderer to the browser. - -@@ -443,7 +433,6 @@ IPC_SYNC_MESSAGE_ROUTED1_1(PrintHostMsg_ScriptedPrint, - PrintMsg_PrintPages_Params - /* settings chosen by the user*/) - --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - // Asks the browser to do print preview. - IPC_MESSAGE_ROUTED1(PrintHostMsg_RequestPrintPreview, - PrintHostMsg_RequestPrintPreview_Params /* params */) -@@ -480,7 +469,6 @@ IPC_SYNC_MESSAGE_ROUTED1_1(PrintHostMsg_CheckForCancel, - IPC_MESSAGE_ROUTED2(PrintHostMsg_MetafileReadyForPrinting, - PrintHostMsg_DidPreviewDocument_Params /* params */, - PrintHostMsg_PreviewIds /* ids */) --#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) - - // This is sent when there are invalid printer settings. - IPC_MESSAGE_ROUTED0(PrintHostMsg_ShowInvalidPrinterSettingsError) -@@ -489,7 +477,6 @@ IPC_MESSAGE_ROUTED0(PrintHostMsg_ShowInvalidPrinterSettingsError) - IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintingFailed, - int /* document cookie */) - --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - // Tell the browser print preview failed. - IPC_MESSAGE_ROUTED2(PrintHostMsg_PrintPreviewFailed, - int /* document cookie */, -@@ -520,6 +507,5 @@ IPC_MESSAGE_ROUTED1(PrintHostMsg_ShowScriptedPrintPreview, - IPC_MESSAGE_ROUTED2(PrintHostMsg_SetOptionsFromDocument, - PrintHostMsg_SetOptionsFromDocument_Params /* params */, - PrintHostMsg_PreviewIds /* ids */) --#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) - - #endif // COMPONENTS_PRINTING_COMMON_PRINT_MESSAGES_H_ -diff --git components/printing/renderer/print_render_frame_helper.cc components/printing/renderer/print_render_frame_helper.cc -index 74f26daa76a2..61a02b46e5a6 100644 ---- components/printing/renderer/print_render_frame_helper.cc -+++ components/printing/renderer/print_render_frame_helper.cc -@@ -351,7 +351,6 @@ bool IsPrintingNodeOrPdfFrame(const blink::WebLocalFrame* frame, - return plugin && plugin->SupportsPaginatedPrint(); - } - --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - // Returns true if the current destination printer is PRINT_TO_PDF. - bool IsPrintToPdfRequested(const base::DictionaryValue& job_settings) { - bool print_to_pdf = false; -@@ -373,7 +372,6 @@ bool PrintingFrameHasPageSizeStyle(blink::WebLocalFrame* frame, - } - return frame_has_custom_page_size_style; - } --#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) - - #if BUILDFLAG(ENABLE_PRINTING) - // Disable scaling when either: -@@ -428,7 +426,6 @@ MarginType GetMarginsForPdf(blink::WebLocalFrame* frame, - : PRINTABLE_AREA_MARGINS; - } - --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - gfx::Size GetPdfPageSize(const gfx::Size& page_size, int dpi) { - return gfx::Size(ConvertUnit(page_size.width(), dpi, kPointsPerInch), - ConvertUnit(page_size.height(), dpi, kPointsPerInch)); -@@ -475,7 +472,6 @@ blink::WebPrintScalingOption GetPrintScalingOption( - } - return blink::kWebPrintScalingOptionFitToPrintableArea; - } --#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) - - // Helper function to scale and round an integer value with a double valued - // scaling. -@@ -1106,10 +1102,8 @@ void PrintRenderFrameHelper::ScriptedPrint(bool user_initiated) { - return; - - if (g_is_preview_enabled) { --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - print_preview_context_.InitWithFrame(web_frame); - RequestPrintPreview(PRINT_PREVIEW_SCRIPTED); --#endif - } else { - auto weak_this = weak_ptr_factory_.GetWeakPtr(); - web_frame->DispatchBeforePrintEvent(); -@@ -1137,13 +1131,11 @@ bool PrintRenderFrameHelper::OnMessageReceived(const IPC::Message& message) { - IPC_BEGIN_MESSAGE_MAP(PrintRenderFrameHelper, message) - IPC_MESSAGE_HANDLER(PrintMsg_PrintPages, OnPrintPages) - IPC_MESSAGE_HANDLER(PrintMsg_PrintForSystemDialog, OnPrintForSystemDialog) --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - IPC_MESSAGE_HANDLER(PrintMsg_InitiatePrintPreview, OnInitiatePrintPreview) - IPC_MESSAGE_HANDLER(PrintMsg_PrintPreview, OnPrintPreview) - IPC_MESSAGE_HANDLER(PrintMsg_PrintingDone, OnPrintingDone) - IPC_MESSAGE_HANDLER(PrintMsg_ClosePrintPreviewDialog, - OnClosePrintPreviewDialog) --#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) - IPC_MESSAGE_HANDLER(PrintMsg_PrintFrameContent, OnPrintFrameContent) - IPC_MESSAGE_HANDLER(PrintMsg_SetPrintingEnabled, OnSetPrintingEnabled) - IPC_MESSAGE_UNHANDLED(handled = false) -@@ -1223,7 +1215,6 @@ void PrintRenderFrameHelper::UpdateFrameMarginsCssInfo( - ignore_css_margins_ = (margins_type != DEFAULT_MARGINS); - } - --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - void PrintRenderFrameHelper::OnPrintPreview( - const base::DictionaryValue& settings) { - if (ipc_nesting_level_ > 1) -@@ -1487,7 +1478,6 @@ int PrintRenderFrameHelper::GetFitToPageScaleFactor( - printable_height / static_cast(uniform_page_size.height); - return static_cast(100.0f * std::min(scale_width, scale_height)); - } --#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) - - void PrintRenderFrameHelper::OnPrintingDone(bool success) { - if (ipc_nesting_level_ > 1) -@@ -1502,7 +1492,6 @@ void PrintRenderFrameHelper::OnSetPrintingEnabled(bool enabled) { - is_printing_enabled_ = enabled; - } - --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - void PrintRenderFrameHelper::OnInitiatePrintPreview(bool has_selection) { - if (ipc_nesting_level_ > 1) - return; -@@ -1513,7 +1502,9 @@ void PrintRenderFrameHelper::OnInitiatePrintPreview(bool has_selection) { - // that instead. - auto plugin = delegate_->GetPdfElement(frame); - if (!plugin.IsNull()) { -+ force_print_preview_ = true; - PrintNode(plugin); -+ force_print_preview_ = false; - return; - } - print_preview_context_.InitWithFrame(frame); -@@ -1525,7 +1516,6 @@ void PrintRenderFrameHelper::OnInitiatePrintPreview(bool has_selection) { - void PrintRenderFrameHelper::OnClosePrintPreviewDialog() { - print_preview_context_.source_frame()->DispatchAfterPrintEvent(); - } --#endif - - void PrintRenderFrameHelper::OnPrintFrameContent( - const PrintMsg_PrintFrame_Params& params) { -@@ -1609,11 +1599,9 @@ void PrintRenderFrameHelper::PrintNode(const blink::WebNode& node) { - - print_node_in_progress_ = true; - -- if (g_is_preview_enabled) { --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) -+ if (g_is_preview_enabled || force_print_preview_) { - print_preview_context_.InitWithNode(node); - RequestPrintPreview(PRINT_PREVIEW_USER_INITIATED_CONTEXT_NODE); --#endif - } else { - // Make a copy of the node, in case RenderView::OnContextMenuClosed() resets - // its |context_menu_node_|. -@@ -1689,13 +1677,11 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame, - void PrintRenderFrameHelper::DidFinishPrinting(PrintingResult result) { - int cookie = - print_pages_params_ ? print_pages_params_->params.document_cookie : 0; --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - PrintHostMsg_PreviewIds ids; - if (print_pages_params_) { - ids.ui_id = print_pages_params_->params.preview_ui_id; - ids.request_id = print_pages_params_->params.preview_request_id; - } --#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) - switch (result) { - case OK: - break; -@@ -1710,7 +1696,6 @@ void PrintRenderFrameHelper::DidFinishPrinting(PrintingResult result) { - } - break; - --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - case FAIL_PREVIEW: - if (!is_print_ready_metafile_sent_) { - if (notify_browser_of_print_failure_) { -@@ -1728,7 +1713,6 @@ void PrintRenderFrameHelper::DidFinishPrinting(PrintingResult result) { - cookie, ids)); - print_preview_context_.Failed(false); - break; --#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) - } - prep_frame_view_.reset(); - print_pages_params_.reset(); -@@ -1901,7 +1885,6 @@ bool PrintRenderFrameHelper::CalculateNumberOfPages(blink::WebLocalFrame* frame, - return true; - } - --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - bool PrintRenderFrameHelper::SetOptionsFromPdfDocument( - PrintHostMsg_SetOptionsFromDocument_Params* options) { - blink::WebLocalFrame* source_frame = print_preview_context_.source_frame(); -@@ -1986,7 +1969,6 @@ bool PrintRenderFrameHelper::UpdatePrintSettings( - print_preview_context_.set_error(PREVIEW_ERROR_INVALID_PRINTER_SETTINGS); - return false; - } --#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) - - void PrintRenderFrameHelper::GetPrintSettingsFromUser( - blink::WebLocalFrame* frame, -@@ -2138,7 +2120,6 @@ bool PrintRenderFrameHelper::CopyMetafileDataToReadOnlySharedMem( - return true; - } - --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - void PrintRenderFrameHelper::ShowScriptedPrintPreview() { - if (is_scripted_preview_delayed_) { - is_scripted_preview_delayed_ = false; -@@ -2264,7 +2245,6 @@ bool PrintRenderFrameHelper::PreviewPageRendered( - Send(new PrintHostMsg_DidPreviewPage(routing_id(), preview_page_params, ids)); - return true; - } --#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) - - PrintRenderFrameHelper::PrintPreviewContext::PrintPreviewContext() = default; - -diff --git components/printing/renderer/print_render_frame_helper.h components/printing/renderer/print_render_frame_helper.h -index 1e2777561ba6..21c3777010b6 100644 ---- components/printing/renderer/print_render_frame_helper.h -+++ components/printing/renderer/print_render_frame_helper.h -@@ -150,10 +150,8 @@ class PrintRenderFrameHelper - OK, - FAIL_PRINT_INIT, - FAIL_PRINT, --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - FAIL_PREVIEW, - INVALID_SETTINGS, --#endif - }; - - // These values are persisted to logs. Entries should not be renumbered and -@@ -195,11 +193,9 @@ class PrintRenderFrameHelper - // Message handlers --------------------------------------------------------- - void OnPrintPages(); - void OnPrintForSystemDialog(); --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - void OnInitiatePrintPreview(bool has_selection); - void OnPrintPreview(const base::DictionaryValue& settings); - void OnClosePrintPreviewDialog(); --#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) - void OnPrintFrameContent(const PrintMsg_PrintFrame_Params& params); - void OnPrintingDone(bool success); - -@@ -213,7 +209,6 @@ class PrintRenderFrameHelper - // Update |ignore_css_margins_| based on settings. - void UpdateFrameMarginsCssInfo(const base::DictionaryValue& settings); - --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - // Prepare frame for creating preview document. - void PrepareFrameForPreviewDocument(); - -@@ -232,7 +227,6 @@ class PrintRenderFrameHelper - - // Helper method to calculate the scale factor for fit-to-page. - int GetFitToPageScaleFactor(const gfx::Rect& printable_area_in_points); --#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) - - // Enable/Disable printing. - void OnSetPrintingEnabled(bool enabled); -@@ -259,7 +253,6 @@ class PrintRenderFrameHelper - const blink::WebNode& node, - int* number_of_pages); - --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - // Set options for print preset from source PDF document. - bool SetOptionsFromPdfDocument( - PrintHostMsg_SetOptionsFromDocument_Params* options); -@@ -270,7 +263,6 @@ class PrintRenderFrameHelper - bool UpdatePrintSettings(blink::WebLocalFrame* frame, - const blink::WebNode& node, - const base::DictionaryValue& passed_job_settings); --#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) - - // Get final print settings from the user. - // WARNING: |this| may be gone after this method returns. -@@ -352,7 +344,6 @@ class PrintRenderFrameHelper - bool IsScriptInitiatedPrintAllowed(blink::WebLocalFrame* frame, - bool user_initiated); - --#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - // Shows scripted print preview when options from plugin are available. - void ShowScriptedPrintPreview(); - -@@ -371,7 +362,6 @@ class PrintRenderFrameHelper - // Returns true if print preview should continue, false on failure. - bool PreviewPageRendered(int page_number, - std::unique_ptr metafile); --#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) - - void SetPrintPagesParams(const PrintMsg_PrintPages_Params& settings); - -@@ -526,6 +516,7 @@ class PrintRenderFrameHelper - ScriptingThrottler scripting_throttler_; - - bool print_node_in_progress_ = false; -+ bool force_print_preview_ = false; - PrintPreviewContext print_preview_context_; - bool is_loading_ = false; - bool is_scripted_preview_delayed_ = false; -diff --git components/printing_component_strings.grdp components/printing_component_strings.grdp -index f3cbf563dee3..d899aab89dfd 100644 ---- components/printing_component_strings.grdp -+++ components/printing_component_strings.grdp -@@ -1,12 +1,10 @@ - - -- - - - $1HP LaserJet on $2printserver - - -- - - - PDF Compositor Service -diff --git components/pwg_encoder/BUILD.gn components/pwg_encoder/BUILD.gn -index 96ae254116a9..3697d6034300 100644 ---- components/pwg_encoder/BUILD.gn -+++ components/pwg_encoder/BUILD.gn -@@ -4,8 +4,6 @@ - - import("//printing/buildflags/buildflags.gni") - --assert(enable_print_preview) -- - static_library("pwg_encoder") { - sources = [ - "bitmap_image.cc", diff --git a/patch/patches/print_preview_123.patch b/patch/patches/print_preview_123.patch new file mode 100644 index 000000000..6b9945694 --- /dev/null +++ b/patch/patches/print_preview_123.patch @@ -0,0 +1,336 @@ +diff --git chrome/browser/download/download_prefs.cc chrome/browser/download/download_prefs.cc +index 323534a720c1..72b232f0ed85 100644 +--- chrome/browser/download/download_prefs.cc ++++ chrome/browser/download/download_prefs.cc +@@ -22,6 +22,7 @@ + #include "base/strings/sys_string_conversions.h" + #include "base/strings/utf_string_conversions.h" + #include "build/build_config.h" ++#include "cef/libcef/features/features.h" + #include "chrome/browser/download/chrome_download_manager_delegate.h" + #include "chrome/browser/download/download_core_service_factory.h" + #include "chrome/browser/download/download_core_service_impl.h" +@@ -52,6 +53,10 @@ + #include "chrome/browser/ui/pdf/adobe_reader_info_win.h" + #endif + ++#if BUILDFLAG(ENABLE_CEF) ++#include "cef/libcef/browser/browser_context.h" ++#endif ++ + using content::BrowserContext; + using content::BrowserThread; + using content::DownloadManager; +@@ -303,7 +308,11 @@ DownloadPrefs* DownloadPrefs::FromDownloadManager( + // static + DownloadPrefs* DownloadPrefs::FromBrowserContext( + content::BrowserContext* context) { ++#if !BUILDFLAG(ENABLE_CEF) + return FromDownloadManager(BrowserContext::GetDownloadManager(context)); ++#else ++ return CefBrowserContext::GetForContext(context)->GetDownloadPrefs(); ++#endif + } + + bool DownloadPrefs::IsFromTrustedSource(const download::DownloadItem& item) { +diff --git chrome/browser/printing/print_preview_dialog_controller.cc chrome/browser/printing/print_preview_dialog_controller.cc +index c26ddaa9aa12..ad181fdc7478 100644 +--- chrome/browser/printing/print_preview_dialog_controller.cc ++++ chrome/browser/printing/print_preview_dialog_controller.cc +@@ -16,6 +16,7 @@ + #include "base/path_service.h" + #include "base/strings/utf_string_conversions.h" + #include "build/build_config.h" ++#include "cef/libcef/features/features.h" + #include "chrome/browser/browser_process.h" + #include "chrome/browser/chrome_notification_types.h" + #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" +@@ -420,8 +421,11 @@ WebContents* PrintPreviewDialogController::CreatePrintPreviewDialog( + content::HostZoomMap::Get(preview_dialog->GetSiteInstance()) + ->SetZoomLevelForHostAndScheme(print_url.scheme(), print_url.host(), 0); + PrintViewManager::CreateForWebContents(preview_dialog); ++ ++#if !BUILDFLAG(ENABLE_CEF) + extensions::ChromeExtensionWebContentsObserver::CreateForWebContents( + preview_dialog); ++#endif + + // Add an entry to the map. + preview_dialog_map_[preview_dialog] = initiator; +diff --git chrome/browser/resources/print_preview/ui/destination_dialog.html chrome/browser/resources/print_preview/ui/destination_dialog.html +index 624b32bd370e..69b6134bcc41 100644 +--- chrome/browser/resources/print_preview/ui/destination_dialog.html ++++ chrome/browser/resources/print_preview/ui/destination_dialog.html +@@ -180,9 +180,7 @@ + + +
+- +- $i18n{manage} +- ++
+ + $i18n{cancel} + +diff --git chrome/browser/resources/print_preview/ui/destination_select.html chrome/browser/resources/print_preview/ui/destination_select.html +index d8369b509661..a0791e34b570 100644 +--- chrome/browser/resources/print_preview/ui/destination_select.html ++++ chrome/browser/resources/print_preview/ui/destination_select.html +@@ -47,10 +47,6 @@ + +- + +