Add print preview support (see issue #123)

Pass the `--enable-print-preview` command-line flag to enable. Currently only
supported on Windows and Linux.
This commit is contained in:
Ananyo Maiti 2019-07-17 14:47:27 -04:00 committed by Marshall Greenblatt
parent cf87c88b05
commit 1669c0afbd
49 changed files with 1098 additions and 1425 deletions

View File

@ -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",

View File

@ -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);
}

View File

@ -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<CefBrowserContext>;
@ -292,6 +299,8 @@ class CefBrowserContext : public ChromeProfileStub,
// SimpleKeyedServiceFactory.
std::unique_ptr<ProfileKey> key_;
std::unique_ptr<DownloadPrefs> download_prefs_;
DISALLOW_COPY_AND_ASSIGN(CefBrowserContext);
};

View File

@ -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<CefBrowserView> 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<CefFocusHandler> 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<content::NavigationController>(
&web_contents->GetController()));

View File

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

View File

@ -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<int>(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());

View File

@ -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<CefBrowserView> 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;

View File

@ -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<CefBrowserView> 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<content::AXLocationChangeNotificationDetails>& 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<CefWebContentsDialogHelper> web_contents_dialog_helper_;
DISALLOW_COPY_AND_ASSIGN(CefBrowserPlatformDelegate);
};

View File

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

View File

@ -118,6 +118,10 @@ class ChromeBrowserProcessStub : public BrowserProcess {
std::unique_ptr<ChromeProfileManagerStub> profile_manager_;
scoped_refptr<extensions::EventRouterForwarder> event_router_forwarder_;
std::unique_ptr<net_log::ChromeNetLog> net_log_;
scoped_refptr<printing::PrintPreviewDialogController>
print_preview_dialog_controller_;
std::unique_ptr<printing::BackgroundPrintingManager>
background_printing_manager_;
std::unique_ptr<net_log::NetExportFileWriter> net_export_file_writer_;
std::unique_ptr<PrefService> local_state_;
// Must be destroyed after |local_state_|.

View File

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

View File

@ -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<CefBrowserHostImpl> GetOwnerBrowserForFrameRoute(

View File

@ -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();
}

View File

@ -49,6 +49,8 @@ class CefBrowserPlatformDelegateNativeLinux
CefEventHandle GetEventHandle(
const content::NativeWebKeyboardEvent& event) const override;
std::unique_ptr<CefMenuRunner> CreateMenuRunner() override;
gfx::Point GetDialogPosition(const gfx::Size& size) override;
gfx::Size GetMaximumDialogSize() override;
private:
void TranslateMouseEvent(blink::WebMouseEvent& result,

View File

@ -44,6 +44,8 @@ class CefBrowserPlatformDelegateNativeMac
std::unique_ptr<CefJavaScriptDialogRunner> CreateJavaScriptDialogRunner()
override;
std::unique_ptr<CefMenuRunner> CreateMenuRunner() override;
gfx::Point GetDialogPosition(const gfx::Size& size) override;
gfx::Size GetMaximumDialogSize() override;
private:
void TranslateMouseEvent(blink::WebMouseEvent& result,

View File

@ -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();
}

View File

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

View File

@ -51,6 +51,8 @@ class CefBrowserPlatformDelegateNativeWin
std::unique_ptr<CefJavaScriptDialogRunner> CreateJavaScriptDialogRunner()
override;
std::unique_ptr<CefMenuRunner> CreateMenuRunner() override;
gfx::Point GetDialogPosition(const gfx::Size& size) override;
gfx::Size GetMaximumDialogSize() override;
private:
void TranslateMouseEvent(blink::WebMouseEvent& result,

View File

@ -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();
}

View File

@ -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);
};

View File

@ -86,6 +86,7 @@ const char* kAllowedWebUIHosts[] = {
chrome::kChromeUINetInternalsHost,
content::kChromeUINetworkErrorHost,
content::kChromeUINetworkErrorsListingHost,
chrome::kChromeUIPrintHost,
content::kChromeUIResourcesHost,
content::kChromeUIServiceWorkerInternalsHost,
chrome::kChromeUISystemInfoHost,

View File

@ -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());

View File

@ -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<PrefService> 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<PrefService> 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.

View File

@ -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<constrained_window::ConstrainedWindowViewsClient>
CreateCefConstrainedWindowViewsClient() {
return base::WrapUnique(new CefConstrainedWindowViewsClient);
}

View File

@ -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 <memory>
#include "components/constrained_window/constrained_window_views_client.h"
// Creates a ConstrainedWindowViewsClient for the Chrome environment.
std::unique_ptr<constrained_window::ConstrainedWindowViewsClient>
CreateCefConstrainedWindowViewsClient();
#endif // CEF_LIBCEF_BROWSER_PRINTING_CONSTRAINED_WINDOW_VIEWS_CLIENT_H_

View File

@ -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 <map>
#include <utility>
@ -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

View File

@ -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<CefPrintViewManager> {
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<PrintPreviewHelper> {
public:
void Initialize(int parent_frame_tree_node_id);
void WebContentsDestroyed() override;
private:
friend class content::WebContentsUserData<PrintPreviewHelper>;
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<CefPrintViewManager>;
// 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<PdfPrintState> 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_

View File

@ -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 <memory>
#include <utility>
#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<PrintMsg_PrintPages>(id));
}
void CefPrintViewManagerBase::PrintDocument(
const scoped_refptr<base::RefCountedMemory>& 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<MetafileSkia> metafile = std::make_unique<MetafileSkia>();
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<base::RefCountedSharedMemoryMapping> 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<content::WebContents>(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<PrintedDocument> 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<JobEventDetails>(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<content::WebContents>(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<content::WebContents>(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<PrintJob>();
print_job_->Initialize(query, RenderSourceName(), number_pages_);
registrar_.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
content::Source<PrintJob>(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<PrintMsg_PrintingDone>(rfh->GetRoutingID(),
printing_succeeded_);
rfh->Send(msg.release());
}
registrar_.Remove(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
content::Source<PrintJob>(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<PrinterQuery> 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<IPC::Message> 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<PrinterQuery> 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

View File

@ -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 <memory>
#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<IPC::Message> 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<PrintJob> 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<base::RefCountedMemory>& 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<PrintQueriesQueue> queue_;
base::WeakPtrFactory<CefPrintViewManagerBase> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(CefPrintViewManagerBase);
};
} // namespace printing
#endif // CEF_LIBCEF_BROWSER_PRINTING_PRINT_VIEW_MANAGER_BASE_H_

View File

@ -52,18 +52,23 @@ class PopupWindowDelegate : public CefWindowDelegate {
CefBrowserPlatformDelegateViews::CefBrowserPlatformDelegateViews(
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate,
CefRefPtr<CefBrowserViewImpl> 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<CefBrowserViewImpl> 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();
}

View File

@ -20,8 +20,6 @@ class CefBrowserPlatformDelegateViews
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate,
CefRefPtr<CefBrowserViewImpl> browser_view);
void set_browser_view(CefRefPtr<CefBrowserViewImpl> 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<CefMenuRunner> 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<CefBrowserViewImpl> browser_view);
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate_;
CefRefPtr<CefBrowserViewImpl> browser_view_;
};

View File

@ -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<CefBrowserViewDelegate> delegate)
: ParentClass(delegate) {}

View File

@ -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 CefViewImpl<CefBrowserViewView,
@ -43,7 +44,8 @@ class CefBrowserViewImpl : public CefViewImpl<CefBrowserViewView,
// Called from CefBrowserPlatformDelegateViews.
void WebContentsCreated(content::WebContents* web_contents);
void BrowserCreated(CefBrowserHostImpl* browser);
void BrowserCreated(CefBrowserHostImpl* browser,
base::RepeatingClosure on_bounds_changed);
void BrowserDestroyed(CefBrowserHostImpl* browser);
// Called to handle accelerators when the event is unhandled by the web
@ -66,6 +68,7 @@ class CefBrowserViewImpl : public CefViewImpl<CefBrowserViewView,
// CefBrowserViewView::Delegate methods:
void OnBrowserViewAdded() override;
void OnBoundsChanged() override;
private:
// Create a new implementation object.
@ -100,6 +103,8 @@ class CefBrowserViewImpl : public CefViewImpl<CefBrowserViewView,
views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_;
bool ignore_next_char_event_ = false;
base::RepeatingClosure on_bounds_changed_;
IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(CefBrowserViewImpl);
DISALLOW_COPY_AND_ASSIGN(CefBrowserViewImpl);
};

View File

@ -32,3 +32,8 @@ void CefBrowserViewView::ViewHierarchyChanged(
browser_view_delegate_->OnBrowserViewAdded();
}
}
void CefBrowserViewView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
ParentClass::OnBoundsChanged(previous_bounds);
browser_view_delegate_->OnBoundsChanged();
}

View File

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

View File

@ -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();
}

View File

@ -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<web_modal::ModalDialogHostObserver>::Unchecked
observer_list_;
base::WeakPtrFactory<CefWebContentsDialogHelper> weak_factory_;
};
#endif // CEF_LIBCEF_BROWSER_WEB_CONTENTS_DIALOG_HELPER_H_

View File

@ -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";

View File

@ -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[];

View File

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

View File

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

View File

@ -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);

View File

@ -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<CefBrowserImpl> CefContentRendererClient::MaybeCreateBrowser(
CefProcessHostMsg_GetNewBrowserInfo_Params params;
content::RenderThread::Get()->Send(new CefProcessHostMsg_GetNewBrowserInfo(
render_frame_routing_id, &params));
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;

View File

@ -6,18 +6,27 @@
#include <vector>
#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) {
// <object> 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(

View File

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

View File

@ -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',
}
]

View File

@ -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 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Printing specific strings (included from generated_resources.grd). -->
<grit-part>
- <if expr="enable_print_preview or is_win">
<message name="IDS_UTILITY_PROCESS_PRINTING_SERVICE_NAME" desc="The name of the utility process used for printing conversions.">
Printing Service
</message>
- </if>
<message name="IDS_PRINT_INVALID_PRINTER_SETTINGS" desc="Message to display when selected printer is not reachable or its settings are invalid.">
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<double>(uniform_page_size.height);
return static_cast<int>(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<MetafileSkia> 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 @@
<?xml version="1.0" encoding="utf-8"?>
<grit-part>
- <if expr="enable_print_preview">
<if expr="is_win">
<message name="IDS_PRINT_PREVIEW_FRIENDLY_WIN_NETWORK_PRINTER_NAME" desc="Friendly name for a printer with a given name on a given server. This uses the same format as the Windows print dialog.">
<ph name="PRINTER_NAME">$1<ex>HP LaserJet</ex></ph> on <ph name="SERVER_NAME">$2<ex>printserver</ex></ph>
</message>
</if>
- </if>
<message name="IDS_PDF_COMPOSITOR_SERVICE_DISPLAY_NAME" desc="The display name (in the system task manager, etc) of the service process used for PDF compositing.">
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",

View File

@ -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 @@
</print-preview-provisional-destination-resolver>
</div>
<div slot="button-container">
- <paper-button on-click="onOpenSettingsPrintPage_">
- $i18n{manage}
- </paper-button>
+ <div></div>
<paper-button class="cancel-button" on-click="onCancelButtonClick_">
$i18n{cancel}
</paper-button>
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 @@
<option value="[[getPdfDestinationKey_()]]" hidden$="[[appKioskMode]]">
$i18n{printToPDF}
</option>
- <option value="[[getGoogleDriveDestinationKey_(activeUser)]]"
- hidden$="[[!activeUser]]">
- $i18n{printToGoogleDrive}
- </option>
<if expr="chromeos">
<option value="noDestinations"
hidden$="[[!noDestinations]]" selected$="[[noDestinations]]">
diff --git chrome/browser/ui/webui/constrained_web_dialog_ui.cc chrome/browser/ui/webui/constrained_web_dialog_ui.cc
index 12f77178ea92..470b13bd7879 100644
--- chrome/browser/ui/webui/constrained_web_dialog_ui.cc
+++ chrome/browser/ui/webui/constrained_web_dialog_ui.cc
@@ -27,6 +27,8 @@
#include "chrome/browser/extensions/tab_helper.h"
#endif
+#include "cef/libcef/features/features.h"
+
using content::RenderFrameHost;
using content::RenderViewHost;
using content::WebContents;
@@ -57,8 +59,10 @@ class ConstrainedWebDialogDelegateUserData
ConstrainedWebDialogUI::ConstrainedWebDialogUI(content::WebUI* web_ui)
: WebUIController(web_ui) {
#if BUILDFLAG(ENABLE_EXTENSIONS)
+#if !BUILDFLAG(ENABLE_CEF)
extensions::TabHelper::CreateForWebContents(web_ui->GetWebContents());
#endif
+#endif
}
ConstrainedWebDialogUI::~ConstrainedWebDialogUI() {
diff --git chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc
index e0d6a9034332..d99eb0bfe967 100644
--- chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc
+++ chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc
@@ -144,8 +144,10 @@ PdfPrinterHandler::PdfPrinterHandler(Profile* profile,
weak_ptr_factory_(this) {}
PdfPrinterHandler::~PdfPrinterHandler() {
+#if !BUILDFLAG(ENABLE_CEF)
if (select_file_dialog_.get())
select_file_dialog_->ListenerDestroyed();
+#endif
}
void PdfPrinterHandler::Reset() {
@@ -180,12 +182,14 @@ void PdfPrinterHandler::StartPrint(
return;
}
+#if !BUILDFLAG(ENABLE_CEF)
if (select_file_dialog_ &&
select_file_dialog_->IsRunning(
platform_util::GetTopLevel(preview_web_contents_->GetNativeView()))) {
// Dialog is already showing.
return;
}
+#endif
DCHECK(!print_callback_);
print_callback_ = std::move(callback);
@@ -324,7 +328,11 @@ void PdfPrinterHandler::SelectFile(const base::FilePath& default_filename,
// If the directory is empty there is no reason to create it or use the
// default location.
if (path.empty()) {
+#if !BUILDFLAG(ENABLE_CEF)
OnDirectorySelected(default_filename, path);
+#else
+ ShowCefSaveAsDialog(initiator, default_filename, path);
+#endif
return;
}
@@ -334,8 +342,14 @@ void PdfPrinterHandler::SelectFile(const base::FilePath& default_filename,
base::PostTaskWithTraitsAndReplyWithResult(
FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
base::BindOnce(&SelectSaveDirectory, path, default_path),
+#if !BUILDFLAG(ENABLE_CEF)
base::BindOnce(&PdfPrinterHandler::OnDirectorySelected,
weak_ptr_factory_.GetWeakPtr(), default_filename));
+#else
+ base::BindOnce(&PdfPrinterHandler::ShowCefSaveAsDialog,
+ weak_ptr_factory_.GetWeakPtr(), initiator,
+ default_filename));
+#endif
}
void PdfPrinterHandler::PostPrintToPdfTask() {
@@ -351,6 +365,7 @@ void PdfPrinterHandler::OnGotUniqueFileName(const base::FilePath& path) {
FileSelected(path, 0, nullptr);
}
+#if !BUILDFLAG(ENABLE_CEF)
void PdfPrinterHandler::OnDirectorySelected(const base::FilePath& filename,
const base::FilePath& directory) {
base::FilePath path = directory.Append(filename);
@@ -375,5 +390,36 @@ void PdfPrinterHandler::OnDirectorySelected(const base::FilePath& filename,
&file_type_info, 0, base::FilePath::StringType(),
platform_util::GetTopLevel(preview_web_contents_->GetNativeView()), NULL);
}
+#else
+void PdfPrinterHandler::ShowCefSaveAsDialog(content::WebContents* initiator,
+ const base::FilePath& filename,
+ const base::FilePath& directory) {
+ CefRefPtr<CefBrowserHostImpl> cef_browser =
+ CefBrowserHostImpl::GetBrowserForContents(initiator);
+ if (!cef_browser)
+ return;
+
+ base::FilePath path = directory.Append(filename);
+
+ CefFileDialogRunner::FileChooserParams params;
+ params.mode = blink::mojom::FileChooserParams::Mode::kSave;
+ params.default_file_name = path;
+ params.accept_types.push_back(CefString(path.Extension()));
+
+ cef_browser->RunFileChooser(
+ params, base::Bind(&PdfPrinterHandler::SaveAsDialogDismissed,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void PdfPrinterHandler::SaveAsDialogDismissed(
+ int selected_accept_filter,
+ const std::vector<base::FilePath>& file_paths) {
+ if (file_paths.size() == 1) {
+ FileSelected(file_paths[0], 0, nullptr);
+ } else {
+ FileSelectionCanceled(nullptr);
+ }
+}
+#endif
} // namespace printing
diff --git chrome/browser/ui/webui/print_preview/pdf_printer_handler.h chrome/browser/ui/webui/print_preview/pdf_printer_handler.h
index eae9098f2136..b4cffbcceb02 100644
--- chrome/browser/ui/webui/print_preview/pdf_printer_handler.h
+++ chrome/browser/ui/webui/print_preview/pdf_printer_handler.h
@@ -11,13 +11,19 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
+#include "cef/libcef/features/features.h"
#include "chrome/browser/ui/webui/print_preview/printer_handler.h"
+
+#if !BUILDFLAG(ENABLE_CEF)
#include "ui/shell_dialogs/select_file_dialog.h"
+#else
+#include "cef/libcef/browser/browser_host_impl.h"
+#endif
namespace base {
class FilePath;
class RefCountedMemory;
-}
+} // namespace base
namespace content {
class WebContents;
@@ -78,17 +84,28 @@ class PdfPrinterHandler : public PrinterHandler,
// The print preview web contents. Protected so unit tests can access it.
content::WebContents* const preview_web_contents_;
+#if !BUILDFLAG(ENABLE_CEF)
// The underlying dialog object. Protected so unit tests can access it.
scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
+#endif
private:
void PostPrintToPdfTask();
void OnGotUniqueFileName(const base::FilePath& path);
+#if !BUILDFLAG(ENABLE_CEF)
// Prompts the user to save the file. The dialog will default to saving
// the file with name |filename| in |directory|.
void OnDirectorySelected(const base::FilePath& filename,
const base::FilePath& directory);
+#else
+ void ShowCefSaveAsDialog(content::WebContents* initiator,
+ const base::FilePath& filename,
+ const base::FilePath& directory);
+
+ void SaveAsDialogDismissed(int selected_accept_filter,
+ const std::vector<base::FilePath>& file_paths);
+#endif
Profile* const profile_;
StickySettings* const sticky_settings_;
diff --git chrome/browser/ui/webui/print_preview/print_preview_handler.cc chrome/browser/ui/webui/print_preview/print_preview_handler.cc
index 47528eaccd78..2ecd9e3d5c03 100644
--- chrome/browser/ui/webui/print_preview/print_preview_handler.cc
+++ chrome/browser/ui/webui/print_preview/print_preview_handler.cc
@@ -26,6 +26,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/values.h"
#include "build/build_config.h"
+#include "cef/libcef/features/features.h"
#include "chrome/browser/app_mode/app_mode_utils.h"
#include "chrome/browser/bad_message.h"
#include "chrome/browser/browser_process.h"
@@ -1243,6 +1244,9 @@ PrinterHandler* PrintPreviewHandler::GetPrinterHandler(
}
return privet_printer_handler_.get();
}
+#else // !BUILDFLAG(ENABLE_SERVICE_DISCOVERY)
+ if (printer_type == PrinterType::kPrivetPrinter)
+ return nullptr;
#endif
if (printer_type == PrinterType::kPdfPrinter) {
if (!pdf_printer_handler_) {
@@ -1325,6 +1329,7 @@ void PrintPreviewHandler::OnPrintResult(const std::string& callback_id,
}
void PrintPreviewHandler::RegisterForGaiaCookieChanges() {
+#if !BUILDFLAG(ENABLE_CEF)
DCHECK(!identity_manager_);
cloud_print_enabled_ =
GetPrefs()->GetBoolean(prefs::kCloudPrintSubmitEnabled);
@@ -1340,6 +1345,7 @@ void PrintPreviewHandler::RegisterForGaiaCookieChanges() {
identity_manager_ = IdentityManagerFactory::GetForProfile(profile);
identity_manager_->AddObserver(this);
+#endif
}
void PrintPreviewHandler::UnregisterForGaiaCookieChanges() {
diff --git chrome/browser/ui/webui/print_preview/print_preview_ui.cc chrome/browser/ui/webui/print_preview/print_preview_ui.cc
index f90198efcf2a..d866bf90c13a 100644
--- chrome/browser/ui/webui/print_preview/print_preview_ui.cc
+++ chrome/browser/ui/webui/print_preview/print_preview_ui.cc
@@ -25,6 +25,7 @@
#include "base/synchronization/lock.h"
#include "base/values.h"
#include "build/build_config.h"
+#include "cef/libcef/features/features.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/printing/background_printing_manager.h"
#include "chrome/browser/printing/print_preview_data_service.h"
@@ -73,12 +74,16 @@ namespace printing {
namespace {
+#if BUILDFLAG(ENABLE_CEF)
+const char kBasicPrintShortcut[] = "";
+#else
#if defined(OS_MACOSX)
// U+0028 U+21E7 U+2318 U+0050 U+0029 in UTF8
const char kBasicPrintShortcut[] = "\x28\xE2\x8c\xA5\xE2\x8C\x98\x50\x29";
#elif !defined(OS_CHROMEOS)
const char kBasicPrintShortcut[] = "(Ctrl+Shift+P)";
#endif
+#endif
PrintPreviewUI::TestDelegate* g_test_delegate = nullptr;

View File

@ -236,8 +236,10 @@ def GetRequiredArgs():
result = {
# Set ENABLE_PRINTING=1 ENABLE_BASIC_PRINTING=1.
'enable_basic_printing': True,
'enable_print_preview': False,
# ENABLE_SERVICE_DISCOVERY=0 for print preview support
'enable_print_preview': True,
'optimize_webui': True,
'enable_service_discovery': False,
# Enable support for Widevine CDM.
'enable_widevine': True,