Add support for printing via CefBrowserHost::Print() and JavaScript window.print() (issue #505).
git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1479 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
f248b937f9
commit
bc1ea4974a
49
cef.gyp
49
cef.gyp
|
@ -439,6 +439,7 @@
|
||||||
[ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
|
[ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
'<(DEPTH)/build/linux/system.gyp:gtk',
|
'<(DEPTH)/build/linux/system.gyp:gtk',
|
||||||
|
'<(DEPTH)/build/linux/system.gyp:gtkprint',
|
||||||
],
|
],
|
||||||
'sources': [
|
'sources': [
|
||||||
'tests/cefclient/resource_util_linux.cpp',
|
'tests/cefclient/resource_util_linux.cpp',
|
||||||
|
@ -530,8 +531,9 @@
|
||||||
'dependencies':[
|
'dependencies':[
|
||||||
'<(DEPTH)/base/allocator/allocator.gyp:allocator',
|
'<(DEPTH)/base/allocator/allocator.gyp:allocator',
|
||||||
'<(DEPTH)/build/linux/system.gyp:gtk',
|
'<(DEPTH)/build/linux/system.gyp:gtk',
|
||||||
|
'<(DEPTH)/build/linux/system.gyp:gtkprint',
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -557,6 +559,7 @@
|
||||||
[ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
|
[ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
'<(DEPTH)/build/linux/system.gyp:gtk',
|
'<(DEPTH)/build/linux/system.gyp:gtk',
|
||||||
|
'<(DEPTH)/build/linux/system.gyp:gtkprint',
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
],
|
],
|
||||||
|
@ -768,6 +771,7 @@
|
||||||
'<(DEPTH)/third_party/WebKit/public/platform',
|
'<(DEPTH)/third_party/WebKit/public/platform',
|
||||||
'<(DEPTH)/third_party/WebKit/public/web',
|
'<(DEPTH)/third_party/WebKit/public/web',
|
||||||
# CEF grit resource includes
|
# CEF grit resource includes
|
||||||
|
'<(DEPTH)/cef/libcef/resources/grit_stub',
|
||||||
'<(grit_out_dir)',
|
'<(grit_out_dir)',
|
||||||
'<(SHARED_INTERMEDIATE_DIR)/content/browser/tracing',
|
'<(SHARED_INTERMEDIATE_DIR)/content/browser/tracing',
|
||||||
'<(SHARED_INTERMEDIATE_DIR)/ui/ui_strings',
|
'<(SHARED_INTERMEDIATE_DIR)/ui/ui_strings',
|
||||||
|
@ -831,6 +835,8 @@
|
||||||
'libcef/browser/browser_settings.h',
|
'libcef/browser/browser_settings.h',
|
||||||
'libcef/browser/browser_urlrequest_impl.cc',
|
'libcef/browser/browser_urlrequest_impl.cc',
|
||||||
'libcef/browser/browser_urlrequest_impl.h',
|
'libcef/browser/browser_urlrequest_impl.h',
|
||||||
|
'libcef/browser/chrome_browser_process_stub.cc',
|
||||||
|
'libcef/browser/chrome_browser_process_stub.h',
|
||||||
'libcef/browser/chrome_scheme_handler.cc',
|
'libcef/browser/chrome_scheme_handler.cc',
|
||||||
'libcef/browser/chrome_scheme_handler.h',
|
'libcef/browser/chrome_scheme_handler.h',
|
||||||
'libcef/browser/content_browser_client.cc',
|
'libcef/browser/content_browser_client.cc',
|
||||||
|
@ -868,6 +874,12 @@
|
||||||
'libcef/browser/origin_whitelist_impl.cc',
|
'libcef/browser/origin_whitelist_impl.cc',
|
||||||
'libcef/browser/origin_whitelist_impl.h',
|
'libcef/browser/origin_whitelist_impl.h',
|
||||||
'libcef/browser/path_util_impl.cc',
|
'libcef/browser/path_util_impl.cc',
|
||||||
|
'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/process_util_impl.cc',
|
||||||
'libcef/browser/proxy_stubs.cc',
|
'libcef/browser/proxy_stubs.cc',
|
||||||
'libcef/browser/render_widget_host_view_osr.cc',
|
'libcef/browser/render_widget_host_view_osr.cc',
|
||||||
|
@ -1004,6 +1016,28 @@
|
||||||
# Include sources for the loadtimes V8 extension.
|
# Include sources for the loadtimes V8 extension.
|
||||||
'<(DEPTH)/chrome/renderer/loadtimes_extension_bindings.h',
|
'<(DEPTH)/chrome/renderer/loadtimes_extension_bindings.h',
|
||||||
'<(DEPTH)/chrome/renderer/loadtimes_extension_bindings.cc',
|
'<(DEPTH)/chrome/renderer/loadtimes_extension_bindings.cc',
|
||||||
|
# Include sources for printing.
|
||||||
|
'<(DEPTH)/chrome/browser/printing/print_job.cc',
|
||||||
|
'<(DEPTH)/chrome/browser/printing/print_job.h',
|
||||||
|
'<(DEPTH)/chrome/browser/printing/print_job_manager.cc',
|
||||||
|
'<(DEPTH)/chrome/browser/printing/print_job_manager.h',
|
||||||
|
'<(DEPTH)/chrome/browser/printing/print_job_worker.cc',
|
||||||
|
'<(DEPTH)/chrome/browser/printing/print_job_worker.h',
|
||||||
|
'<(DEPTH)/chrome/browser/printing/print_job_worker_owner.h',
|
||||||
|
'<(DEPTH)/chrome/browser/printing/print_job_worker_owner.h',
|
||||||
|
'<(DEPTH)/chrome/browser/printing/printer_query.cc',
|
||||||
|
'<(DEPTH)/chrome/browser/printing/printer_query.h',
|
||||||
|
'<(DEPTH)/chrome/common/prerender_messages.h',
|
||||||
|
'<(DEPTH)/chrome/common/print_messages.cc',
|
||||||
|
'<(DEPTH)/chrome/common/print_messages.h',
|
||||||
|
'<(DEPTH)/chrome/renderer/prerender/prerender_helper.cc',
|
||||||
|
'<(DEPTH)/chrome/renderer/prerender/prerender_helper.h',
|
||||||
|
'<(DEPTH)/chrome/renderer/printing/print_web_view_helper.cc',
|
||||||
|
'<(DEPTH)/chrome/renderer/printing/print_web_view_helper.h',
|
||||||
|
# Include header for stub creation (BrowserProcess) so print_job_worker can
|
||||||
|
# determine the current locale.
|
||||||
|
'<(DEPTH)/chrome/browser/browser_process.cc',
|
||||||
|
'<(DEPTH)/chrome/browser/browser_process.h',
|
||||||
],
|
],
|
||||||
'conditions': [
|
'conditions': [
|
||||||
['OS=="win"', {
|
['OS=="win"', {
|
||||||
|
@ -1024,6 +1058,8 @@
|
||||||
'<(DEPTH)/ui/views/controls/menu/menu_listener.h',
|
'<(DEPTH)/ui/views/controls/menu/menu_listener.h',
|
||||||
'<(DEPTH)/ui/views/controls/menu/native_menu_win.cc',
|
'<(DEPTH)/ui/views/controls/menu/native_menu_win.cc',
|
||||||
'<(DEPTH)/ui/views/controls/menu/native_menu_win.h',
|
'<(DEPTH)/ui/views/controls/menu/native_menu_win.h',
|
||||||
|
# Include sources for printing.
|
||||||
|
'<(DEPTH)/chrome/renderer/printing/print_web_view_helper_win.cc',
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
[ 'OS=="mac"', {
|
[ 'OS=="mac"', {
|
||||||
|
@ -1045,9 +1081,14 @@
|
||||||
'libcef/browser/text_input_client_osr_mac.h',
|
'libcef/browser/text_input_client_osr_mac.h',
|
||||||
'libcef/browser/web_contents_view_osr.cc',
|
'libcef/browser/web_contents_view_osr.cc',
|
||||||
'libcef/browser/web_contents_view_osr.h',
|
'libcef/browser/web_contents_view_osr.h',
|
||||||
|
# Include sources for printing.
|
||||||
|
'<(DEPTH)/chrome/renderer/printing/print_web_view_helper_mac.mm',
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
[ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
|
[ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
|
||||||
|
'dependencies':[
|
||||||
|
'<(DEPTH)/build/linux/system.gyp:gtkprint',
|
||||||
|
],
|
||||||
'sources': [
|
'sources': [
|
||||||
'<@(includes_linux)',
|
'<@(includes_linux)',
|
||||||
'libcef/browser/browser_host_impl_gtk.cc',
|
'libcef/browser/browser_host_impl_gtk.cc',
|
||||||
|
@ -1065,6 +1106,10 @@
|
||||||
'<(DEPTH)/chrome/browser/ui/gtk/menu_gtk.h',
|
'<(DEPTH)/chrome/browser/ui/gtk/menu_gtk.h',
|
||||||
'<(DEPTH)/chrome/browser/ui/views/event_utils.cc',
|
'<(DEPTH)/chrome/browser/ui/views/event_utils.cc',
|
||||||
'<(DEPTH)/chrome/browser/ui/views/event_utils.h',
|
'<(DEPTH)/chrome/browser/ui/views/event_utils.h',
|
||||||
|
#Include sources for printing.
|
||||||
|
'<(DEPTH)/chrome/browser/printing/print_dialog_gtk.cc',
|
||||||
|
'<(DEPTH)/chrome/browser/printing/print_dialog_gtk.h',
|
||||||
|
'<(DEPTH)/chrome/renderer/printing/print_web_view_helper_linux.cc',
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
],
|
],
|
||||||
|
@ -1334,7 +1379,7 @@
|
||||||
# gtk requires gmodule, but it does not list it as a dependency
|
# gtk requires gmodule, but it does not list it as a dependency
|
||||||
# in some misconfigured systems.
|
# in some misconfigured systems.
|
||||||
# gtkglext is required by the cefclient OSR example.
|
# gtkglext is required by the cefclient OSR example.
|
||||||
'gtk_packages': 'gmodule-2.0 gtk+-2.0 gthread-2.0 gtkglext-1.0',
|
'gtk_packages': 'gmodule-2.0 gtk+-2.0 gthread-2.0 gtkglext-1.0 gtk+-unix-print-2.0',
|
||||||
},
|
},
|
||||||
'direct_dependent_settings': {
|
'direct_dependent_settings': {
|
||||||
'cflags': [
|
'cflags': [
|
||||||
|
|
|
@ -319,6 +319,11 @@ typedef struct _cef_browser_host_t {
|
||||||
void (CEF_CALLBACK *start_download)(struct _cef_browser_host_t* self,
|
void (CEF_CALLBACK *start_download)(struct _cef_browser_host_t* self,
|
||||||
const cef_string_t* url);
|
const cef_string_t* url);
|
||||||
|
|
||||||
|
///
|
||||||
|
// Print the current browser contents.
|
||||||
|
///
|
||||||
|
void (CEF_CALLBACK *print)(struct _cef_browser_host_t* self);
|
||||||
|
|
||||||
///
|
///
|
||||||
// Set whether mouse cursor change is disabled.
|
// Set whether mouse cursor change is disabled.
|
||||||
///
|
///
|
||||||
|
|
|
@ -366,6 +366,12 @@ class CefBrowserHost : public virtual CefBase {
|
||||||
/*--cef()--*/
|
/*--cef()--*/
|
||||||
virtual void StartDownload(const CefString& url) =0;
|
virtual void StartDownload(const CefString& url) =0;
|
||||||
|
|
||||||
|
///
|
||||||
|
// Print the current browser contents.
|
||||||
|
///
|
||||||
|
/*--cef()--*/
|
||||||
|
virtual void Print() =0;
|
||||||
|
|
||||||
///
|
///
|
||||||
// Set whether mouse cursor change is disabled.
|
// Set whether mouse cursor change is disabled.
|
||||||
///
|
///
|
||||||
|
@ -485,7 +491,6 @@ class CefBrowserHost : public virtual CefBase {
|
||||||
///
|
///
|
||||||
/*--cef()--*/
|
/*--cef()--*/
|
||||||
virtual void HandleKeyEventAfterTextInputClient(CefEventHandle keyEvent) =0;
|
virtual void HandleKeyEventAfterTextInputClient(CefEventHandle keyEvent) =0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CEF_INCLUDE_CEF_BROWSER_H_
|
#endif // CEF_INCLUDE_CEF_BROWSER_H_
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "libcef/browser/devtools_delegate.h"
|
#include "libcef/browser/devtools_delegate.h"
|
||||||
#include "libcef/browser/media_capture_devices_dispatcher.h"
|
#include "libcef/browser/media_capture_devices_dispatcher.h"
|
||||||
#include "libcef/browser/navigate_params.h"
|
#include "libcef/browser/navigate_params.h"
|
||||||
|
#include "libcef/browser/printing/print_view_manager.h"
|
||||||
#include "libcef/browser/render_widget_host_view_osr.h"
|
#include "libcef/browser/render_widget_host_view_osr.h"
|
||||||
#include "libcef/browser/request_context_impl.h"
|
#include "libcef/browser/request_context_impl.h"
|
||||||
#include "libcef/browser/scheme_handler.h"
|
#include "libcef/browser/scheme_handler.h"
|
||||||
|
@ -603,6 +604,18 @@ void CefBrowserHostImpl::StartDownload(const CefString& url) {
|
||||||
manager->DownloadUrl(params.Pass());
|
manager->DownloadUrl(params.Pass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CefBrowserHostImpl::Print() {
|
||||||
|
if (CEF_CURRENTLY_ON_UIT()) {
|
||||||
|
if (!web_contents_)
|
||||||
|
return;
|
||||||
|
printing::PrintViewManager::FromWebContents(
|
||||||
|
web_contents_.get())->PrintNow();
|
||||||
|
} else {
|
||||||
|
CEF_POST_TASK(CEF_UIT,
|
||||||
|
base::Bind(&CefBrowserHostImpl::Print, this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CefBrowserHostImpl::SetMouseCursorChangeDisabled(bool disabled) {
|
void CefBrowserHostImpl::SetMouseCursorChangeDisabled(bool disabled) {
|
||||||
base::AutoLock lock_scope(state_lock_);
|
base::AutoLock lock_scope(state_lock_);
|
||||||
mouse_cursor_change_disabled_ = disabled;
|
mouse_cursor_change_disabled_ = disabled;
|
||||||
|
@ -2114,6 +2127,8 @@ CefBrowserHostImpl::CefBrowserHostImpl(
|
||||||
CefString(), CefString(),
|
CefString(), CefString(),
|
||||||
CefFrameHostImpl::kInvalidFrameId);
|
CefFrameHostImpl::kInvalidFrameId);
|
||||||
|
|
||||||
|
printing::PrintViewManager::CreateForWebContents(web_contents_.get());
|
||||||
|
|
||||||
// Make sure RenderViewCreated is called at least one time.
|
// Make sure RenderViewCreated is called at least one time.
|
||||||
RenderViewCreated(web_contents->GetRenderViewHost());
|
RenderViewCreated(web_contents->GetRenderViewHost());
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||||
const std::vector<CefString>& accept_types,
|
const std::vector<CefString>& accept_types,
|
||||||
CefRefPtr<CefRunFileDialogCallback> callback) OVERRIDE;
|
CefRefPtr<CefRunFileDialogCallback> callback) OVERRIDE;
|
||||||
virtual void StartDownload(const CefString& url) OVERRIDE;
|
virtual void StartDownload(const CefString& url) OVERRIDE;
|
||||||
|
virtual void Print() OVERRIDE;
|
||||||
virtual void SetMouseCursorChangeDisabled(bool disabled) OVERRIDE;
|
virtual void SetMouseCursorChangeDisabled(bool disabled) OVERRIDE;
|
||||||
virtual bool IsMouseCursorChangeDisabled() OVERRIDE;
|
virtual bool IsMouseCursorChangeDisabled() OVERRIDE;
|
||||||
virtual bool IsWindowRenderingDisabled() OVERRIDE;
|
virtual bool IsWindowRenderingDisabled() OVERRIDE;
|
||||||
|
|
|
@ -26,6 +26,10 @@
|
||||||
#include "ui/base/resource/resource_bundle.h"
|
#include "ui/base/resource/resource_bundle.h"
|
||||||
#include "v8/include/v8.h"
|
#include "v8/include/v8.h"
|
||||||
|
|
||||||
|
#if defined(OS_LINUX)
|
||||||
|
#include "chrome/browser/printing/print_dialog_gtk.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
CefBrowserMainParts::CefBrowserMainParts(
|
CefBrowserMainParts::CefBrowserMainParts(
|
||||||
const content::MainFunctionParams& parameters)
|
const content::MainFunctionParams& parameters)
|
||||||
: BrowserMainParts(),
|
: BrowserMainParts(),
|
||||||
|
@ -48,6 +52,11 @@ void CefBrowserMainParts::PostMainMessageLoopStart() {
|
||||||
// CEF's internal handling of "chrome://tracing".
|
// CEF's internal handling of "chrome://tracing".
|
||||||
content::WebUIControllerFactory::UnregisterFactoryForTesting(
|
content::WebUIControllerFactory::UnregisterFactoryForTesting(
|
||||||
content::ContentWebUIControllerFactory::GetInstance());
|
content::ContentWebUIControllerFactory::GetInstance());
|
||||||
|
|
||||||
|
#if defined(OS_LINUX)
|
||||||
|
printing::PrintingContextGtk::SetCreatePrintDialogFunction(
|
||||||
|
&PrintDialogGtk::CreatePrintDialog);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int CefBrowserMainParts::PreCreateThreads() {
|
int CefBrowserMainParts::PreCreateThreads() {
|
||||||
|
|
|
@ -29,6 +29,8 @@ PrefService* CefBrowserPrefStore::CreateService() {
|
||||||
CefMediaCaptureDevicesDispatcher::RegisterPrefs(registry);
|
CefMediaCaptureDevicesDispatcher::RegisterPrefs(registry);
|
||||||
PrefProxyConfigTrackerImpl::RegisterPrefs(registry);
|
PrefProxyConfigTrackerImpl::RegisterPrefs(registry);
|
||||||
|
|
||||||
|
registry->RegisterBooleanPref(prefs::kPrintingEnabled, true);
|
||||||
|
|
||||||
return builder.Create(registry);
|
return builder.Create(registry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,271 @@
|
||||||
|
// Copyright (c) 2013 The Chromium Embedded Framework Authors.
|
||||||
|
// Portions (c) 2011 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/chrome_browser_process_stub.h"
|
||||||
|
#include "libcef/browser/context.h"
|
||||||
|
|
||||||
|
#include "base/memory/scoped_ptr.h"
|
||||||
|
#include "ui/message_center/message_center.h"
|
||||||
|
|
||||||
|
ChromeBrowserProcessStub::ChromeBrowserProcessStub()
|
||||||
|
: locale_("en-US") {
|
||||||
|
}
|
||||||
|
|
||||||
|
ChromeBrowserProcessStub::~ChromeBrowserProcessStub() {
|
||||||
|
g_browser_process = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChromeBrowserProcessStub::ResourceDispatcherHostCreated() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
};
|
||||||
|
|
||||||
|
void ChromeBrowserProcessStub::EndSession() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
};
|
||||||
|
|
||||||
|
MetricsService* ChromeBrowserProcessStub::metrics_service() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOThread* ChromeBrowserProcessStub::io_thread() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
WatchDogThread* ChromeBrowserProcessStub::watchdog_thread() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProfileManager* ChromeBrowserProcessStub::profile_manager() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrefService* ChromeBrowserProcessStub::local_state() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
net::URLRequestContextGetter*
|
||||||
|
ChromeBrowserProcessStub::system_request_context() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
chrome_variations::VariationsService*
|
||||||
|
ChromeBrowserProcessStub::variations_service() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BrowserProcessPlatformPart* ChromeBrowserProcessStub::platform_part() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
extensions::EventRouterForwarder*
|
||||||
|
ChromeBrowserProcessStub::extension_event_router_forwarder() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationUIManager* ChromeBrowserProcessStub::notification_ui_manager() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
message_center::MessageCenter* ChromeBrowserProcessStub::message_center() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
policy::BrowserPolicyConnector*
|
||||||
|
ChromeBrowserProcessStub::browser_policy_connector() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
policy::PolicyService* ChromeBrowserProcessStub::policy_service() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
IconManager* ChromeBrowserProcessStub::icon_manager() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLStringManager* ChromeBrowserProcessStub::gl_string_manager() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
GpuModeManager* ChromeBrowserProcessStub::gpu_mode_manager() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderWidgetSnapshotTaker*
|
||||||
|
ChromeBrowserProcessStub::GetRenderWidgetSnapshotTaker() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
AutomationProviderList*
|
||||||
|
ChromeBrowserProcessStub::GetAutomationProviderList() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChromeBrowserProcessStub::CreateDevToolsHttpProtocolHandler(
|
||||||
|
chrome::HostDesktopType host_desktop_type,
|
||||||
|
const std::string& ip,
|
||||||
|
int port,
|
||||||
|
const std::string& frontend_url) {
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int ChromeBrowserProcessStub::AddRefModule() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int ChromeBrowserProcessStub::ReleaseModule() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChromeBrowserProcessStub::IsShuttingDown() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
printing::PrintJobManager* ChromeBrowserProcessStub::print_job_manager() {
|
||||||
|
return CefContext::Get()->print_job_manager();
|
||||||
|
}
|
||||||
|
|
||||||
|
printing::PrintPreviewDialogController*
|
||||||
|
ChromeBrowserProcessStub::print_preview_dialog_controller() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
printing::BackgroundPrintingManager*
|
||||||
|
ChromeBrowserProcessStub::background_printing_manager() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
IntranetRedirectDetector*
|
||||||
|
ChromeBrowserProcessStub::intranet_redirect_detector() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string &ChromeBrowserProcessStub::GetApplicationLocale() {
|
||||||
|
DCHECK(!locale_.empty());
|
||||||
|
return locale_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChromeBrowserProcessStub::SetApplicationLocale(const std::string& locale) {
|
||||||
|
locale_ = locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
DownloadStatusUpdater* ChromeBrowserProcessStub::download_status_updater() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
DownloadRequestLimiter* ChromeBrowserProcessStub::download_request_limiter() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackgroundModeManager* ChromeBrowserProcessStub::background_mode_manager() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChromeBrowserProcessStub::set_background_mode_manager_for_test(
|
||||||
|
scoped_ptr<BackgroundModeManager> manager) {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusTray* ChromeBrowserProcessStub::status_tray() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SafeBrowsingService* ChromeBrowserProcessStub::safe_browsing_service() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
safe_browsing::ClientSideDetectionService*
|
||||||
|
ChromeBrowserProcessStub::safe_browsing_detection_service() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS)
|
||||||
|
void ChromeBrowserProcessStub::StartAutoupdateTimer() {
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ChromeNetLog* ChromeBrowserProcessStub::net_log() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
prerender::PrerenderTracker* ChromeBrowserProcessStub::prerender_tracker() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComponentUpdateService* ChromeBrowserProcessStub::component_updater() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CRLSetFetcher* ChromeBrowserProcessStub::crl_set_fetcher() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PnaclComponentInstaller*
|
||||||
|
ChromeBrowserProcessStub::pnacl_component_installer() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BookmarkPromptController*
|
||||||
|
ChromeBrowserProcessStub::bookmark_prompt_controller() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
MediaFileSystemRegistry*
|
||||||
|
ChromeBrowserProcessStub::media_file_system_registry() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChromeBrowserProcessStub::created_local_state() const {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
StorageMonitor* ChromeBrowserProcessStub::storage_monitor() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(ENABLE_WEBRTC)
|
||||||
|
WebRtcLogUploader* ChromeBrowserProcessStub::webrtc_log_uploader() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,103 @@
|
||||||
|
// Copyright (c) 2013 The Chromium Embedded Framework Authors.
|
||||||
|
// Portions (c) 2011 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_CHROME_BROWSER_PROCESS_STUB_H_
|
||||||
|
#define CEF_LIBCEF_BROWSER_CHROME_BROWSER_PROCESS_STUB_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "chrome/browser/browser_process.h"
|
||||||
|
#include "base/compiler_specific.h"
|
||||||
|
#include "base/memory/scoped_ptr.h"
|
||||||
|
|
||||||
|
// This file provides a stub implementation of chrome::BrowserProcess so that
|
||||||
|
// PrintJobWorker can determine the current locale.
|
||||||
|
|
||||||
|
class BackgroundModeManager {
|
||||||
|
public:
|
||||||
|
BackgroundModeManager();
|
||||||
|
virtual ~BackgroundModeManager();
|
||||||
|
private:
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(BackgroundModeManager);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ChromeBrowserProcessStub : public BrowserProcess {
|
||||||
|
public:
|
||||||
|
ChromeBrowserProcessStub();
|
||||||
|
virtual ~ChromeBrowserProcessStub();
|
||||||
|
|
||||||
|
// BrowserProcess implementation.
|
||||||
|
virtual void ResourceDispatcherHostCreated() OVERRIDE;
|
||||||
|
virtual void EndSession() OVERRIDE;
|
||||||
|
virtual MetricsService* metrics_service() OVERRIDE;
|
||||||
|
virtual IOThread* io_thread() OVERRIDE;
|
||||||
|
virtual WatchDogThread* watchdog_thread() OVERRIDE;
|
||||||
|
virtual ProfileManager* profile_manager() OVERRIDE;
|
||||||
|
virtual PrefService* local_state() OVERRIDE;
|
||||||
|
virtual net::URLRequestContextGetter* system_request_context() OVERRIDE;
|
||||||
|
virtual chrome_variations::VariationsService* variations_service() OVERRIDE;
|
||||||
|
virtual BrowserProcessPlatformPart* platform_part() OVERRIDE;
|
||||||
|
virtual extensions::EventRouterForwarder*
|
||||||
|
extension_event_router_forwarder() OVERRIDE;
|
||||||
|
virtual NotificationUIManager* notification_ui_manager() OVERRIDE;
|
||||||
|
virtual message_center::MessageCenter* message_center() OVERRIDE;
|
||||||
|
virtual policy::BrowserPolicyConnector* browser_policy_connector() OVERRIDE;
|
||||||
|
virtual policy::PolicyService* policy_service() OVERRIDE;
|
||||||
|
virtual IconManager* icon_manager() OVERRIDE;
|
||||||
|
virtual GLStringManager* gl_string_manager() OVERRIDE;
|
||||||
|
virtual GpuModeManager* gpu_mode_manager() OVERRIDE;
|
||||||
|
virtual RenderWidgetSnapshotTaker* GetRenderWidgetSnapshotTaker() OVERRIDE;
|
||||||
|
virtual AutomationProviderList* GetAutomationProviderList() OVERRIDE;
|
||||||
|
virtual void CreateDevToolsHttpProtocolHandler(
|
||||||
|
chrome::HostDesktopType host_desktop_type,
|
||||||
|
const std::string& ip,
|
||||||
|
int port,
|
||||||
|
const std::string& frontend_url) OVERRIDE;
|
||||||
|
virtual unsigned int AddRefModule() OVERRIDE;
|
||||||
|
virtual unsigned int ReleaseModule() OVERRIDE;
|
||||||
|
virtual bool IsShuttingDown() OVERRIDE;
|
||||||
|
virtual printing::PrintJobManager* print_job_manager() OVERRIDE;
|
||||||
|
virtual printing::PrintPreviewDialogController*
|
||||||
|
print_preview_dialog_controller() OVERRIDE;
|
||||||
|
virtual printing::BackgroundPrintingManager*
|
||||||
|
background_printing_manager() OVERRIDE;
|
||||||
|
virtual IntranetRedirectDetector* intranet_redirect_detector() OVERRIDE;
|
||||||
|
virtual const std::string& GetApplicationLocale() OVERRIDE;
|
||||||
|
virtual void SetApplicationLocale(const std::string& locale) OVERRIDE;
|
||||||
|
virtual DownloadStatusUpdater* download_status_updater() OVERRIDE;
|
||||||
|
virtual DownloadRequestLimiter* download_request_limiter() OVERRIDE;
|
||||||
|
virtual BackgroundModeManager* background_mode_manager() OVERRIDE;
|
||||||
|
virtual void set_background_mode_manager_for_test(
|
||||||
|
scoped_ptr<BackgroundModeManager> manager) OVERRIDE;
|
||||||
|
virtual StatusTray* status_tray() OVERRIDE;
|
||||||
|
virtual SafeBrowsingService* safe_browsing_service() OVERRIDE;
|
||||||
|
virtual safe_browsing::ClientSideDetectionService*
|
||||||
|
safe_browsing_detection_service() OVERRIDE;
|
||||||
|
|
||||||
|
#if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS)
|
||||||
|
virtual void StartAutoupdateTimer() OVERRIDE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
virtual ChromeNetLog* net_log() OVERRIDE;
|
||||||
|
virtual prerender::PrerenderTracker* prerender_tracker() OVERRIDE;
|
||||||
|
virtual ComponentUpdateService* component_updater() OVERRIDE;
|
||||||
|
virtual CRLSetFetcher* crl_set_fetcher() OVERRIDE;
|
||||||
|
virtual PnaclComponentInstaller* pnacl_component_installer() OVERRIDE;
|
||||||
|
virtual BookmarkPromptController* bookmark_prompt_controller() OVERRIDE;
|
||||||
|
virtual MediaFileSystemRegistry*
|
||||||
|
media_file_system_registry() OVERRIDE;
|
||||||
|
virtual bool created_local_state() const OVERRIDE;
|
||||||
|
virtual StorageMonitor* storage_monitor() OVERRIDE;
|
||||||
|
#if defined(ENABLE_WEBRTC)
|
||||||
|
virtual WebRtcLogUploader* webrtc_log_uploader() OVERRIDE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string locale_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(ChromeBrowserProcessStub);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CEF_LIBCEF_BROWSER_CHROME_BROWSER_PROCESS_STUB_H_
|
|
@ -15,6 +15,7 @@
|
||||||
#include "libcef/browser/browser_settings.h"
|
#include "libcef/browser/browser_settings.h"
|
||||||
#include "libcef/browser/chrome_scheme_handler.h"
|
#include "libcef/browser/chrome_scheme_handler.h"
|
||||||
#include "libcef/browser/media_capture_devices_dispatcher.h"
|
#include "libcef/browser/media_capture_devices_dispatcher.h"
|
||||||
|
#include "libcef/browser/printing/printing_message_filter.h"
|
||||||
#include "libcef/browser/resource_dispatcher_host_delegate.h"
|
#include "libcef/browser/resource_dispatcher_host_delegate.h"
|
||||||
#include "libcef/browser/speech_recognition_manager_delegate.h"
|
#include "libcef/browser/speech_recognition_manager_delegate.h"
|
||||||
#include "libcef/browser/thread_util.h"
|
#include "libcef/browser/thread_util.h"
|
||||||
|
@ -454,6 +455,8 @@ CefContentBrowserClient::OverrideCreateWebContentsView(
|
||||||
void CefContentBrowserClient::RenderProcessHostCreated(
|
void CefContentBrowserClient::RenderProcessHostCreated(
|
||||||
content::RenderProcessHost* host) {
|
content::RenderProcessHost* host) {
|
||||||
host->GetChannel()->AddFilter(new CefBrowserMessageFilter(host));
|
host->GetChannel()->AddFilter(new CefBrowserMessageFilter(host));
|
||||||
|
host->AddFilter(new PrintingMessageFilter(host->GetID()));
|
||||||
|
|
||||||
AddBrowserContextReference(
|
AddBrowserContextReference(
|
||||||
static_cast<CefBrowserContext*>(host->GetBrowserContext()));
|
static_cast<CefBrowserContext*>(host->GetBrowserContext()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "libcef/browser/browser_info.h"
|
#include "libcef/browser/browser_info.h"
|
||||||
#include "libcef/browser/browser_main.h"
|
#include "libcef/browser/browser_main.h"
|
||||||
#include "libcef/browser/browser_message_loop.h"
|
#include "libcef/browser/browser_message_loop.h"
|
||||||
|
#include "libcef/browser/chrome_browser_process_stub.h"
|
||||||
#include "libcef/browser/content_browser_client.h"
|
#include "libcef/browser/content_browser_client.h"
|
||||||
#include "libcef/browser/scheme_handler.h"
|
#include "libcef/browser/scheme_handler.h"
|
||||||
#include "libcef/browser/thread_util.h"
|
#include "libcef/browser/thread_util.h"
|
||||||
|
@ -19,6 +20,7 @@
|
||||||
#include "base/command_line.h"
|
#include "base/command_line.h"
|
||||||
#include "base/file_util.h"
|
#include "base/file_util.h"
|
||||||
#include "base/synchronization/waitable_event.h"
|
#include "base/synchronization/waitable_event.h"
|
||||||
|
#include "chrome/browser/printing/print_job_manager.h"
|
||||||
#include "content/public/app/content_main.h"
|
#include "content/public/app/content_main.h"
|
||||||
#include "content/public/app/content_main_runner.h"
|
#include "content/public/app/content_main_runner.h"
|
||||||
#include "content/public/browser/notification_service.h"
|
#include "content/public/browser/notification_service.h"
|
||||||
|
@ -44,13 +46,13 @@ CefContext* g_context = NULL;
|
||||||
// CefShutdown() has not been explicitly called.
|
// CefShutdown() has not been explicitly called.
|
||||||
class CefForceShutdown {
|
class CefForceShutdown {
|
||||||
public:
|
public:
|
||||||
~CefForceShutdown() {
|
~CefForceShutdown() {
|
||||||
if (g_context) {
|
if (g_context) {
|
||||||
g_context->Shutdown();
|
g_context->Shutdown();
|
||||||
delete g_context;
|
delete g_context;
|
||||||
g_context = NULL;
|
g_context = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} g_force_shutdown;
|
} g_force_shutdown;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -102,6 +104,8 @@ bool CefInitialize(const CefMainArgs& args,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_browser_process = new ChromeBrowserProcessStub();
|
||||||
|
|
||||||
// Create the new global context object.
|
// Create the new global context object.
|
||||||
g_context = new CefContext();
|
g_context = new CefContext();
|
||||||
|
|
||||||
|
@ -267,9 +271,13 @@ bool CefContext::Initialize(const CefMainArgs& args,
|
||||||
|
|
||||||
initialized_ = true;
|
initialized_ = true;
|
||||||
|
|
||||||
// Continue initialization on the UI thread.
|
if (CEF_CURRENTLY_ON_UIT()) {
|
||||||
CEF_POST_TASK(CEF_UIT,
|
OnContextInitialized();
|
||||||
base::Bind(&CefContext::OnContextInitialized, base::Unretained(this)));
|
} else {
|
||||||
|
// Continue initialization on the UI thread.
|
||||||
|
CEF_POST_TASK(CEF_UIT,
|
||||||
|
base::Bind(&CefContext::OnContextInitialized, base::Unretained(this)));
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -329,6 +337,9 @@ void CefContext::OnContextInitialized() {
|
||||||
registrar_->Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
|
registrar_->Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
|
||||||
content::NotificationService::AllBrowserContextsAndSources());
|
content::NotificationService::AllBrowserContextsAndSources());
|
||||||
|
|
||||||
|
// Must be created after the NotificationService.
|
||||||
|
print_job_manager_.reset(new printing::PrintJobManager());
|
||||||
|
|
||||||
// Notify the handler.
|
// Notify the handler.
|
||||||
CefRefPtr<CefApp> app = CefContentClient::Get()->application();
|
CefRefPtr<CefApp> app = CefContentClient::Get()->application();
|
||||||
if (app.get()) {
|
if (app.get()) {
|
||||||
|
@ -343,6 +354,12 @@ void CefContext::FinishShutdownOnUIThread(
|
||||||
base::WaitableEvent* uithread_shutdown_event) {
|
base::WaitableEvent* uithread_shutdown_event) {
|
||||||
CEF_REQUIRE_UIT();
|
CEF_REQUIRE_UIT();
|
||||||
|
|
||||||
|
// Wait for the pending print jobs to finish. Don't do this later, since
|
||||||
|
// this might cause a nested message loop to run, and we don't want pending
|
||||||
|
// tasks to run once teardown has started.
|
||||||
|
print_job_manager_->Shutdown();
|
||||||
|
print_job_manager_.reset(NULL);
|
||||||
|
|
||||||
CefContentBrowserClient::Get()->DestroyAllBrowsers();
|
CefContentBrowserClient::Get()->DestroyAllBrowsers();
|
||||||
|
|
||||||
registrar_.reset();
|
registrar_.reset();
|
||||||
|
|
|
@ -27,6 +27,10 @@ namespace content {
|
||||||
class ContentMainRunner;
|
class ContentMainRunner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace printing {
|
||||||
|
class PrintJobManager;
|
||||||
|
}
|
||||||
|
|
||||||
class CefBrowserHostImpl;
|
class CefBrowserHostImpl;
|
||||||
class CefMainDelegate;
|
class CefMainDelegate;
|
||||||
class CefTraceSubscriber;
|
class CefTraceSubscriber;
|
||||||
|
@ -61,6 +65,10 @@ class CefContext : public content::NotificationObserver {
|
||||||
|
|
||||||
const CefSettings& settings() const { return settings_; }
|
const CefSettings& settings() const { return settings_; }
|
||||||
|
|
||||||
|
printing::PrintJobManager* print_job_manager() const {
|
||||||
|
return print_job_manager_.get();
|
||||||
|
}
|
||||||
|
|
||||||
CefTraceSubscriber* GetTraceSubscriber();
|
CefTraceSubscriber* GetTraceSubscriber();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -95,6 +103,7 @@ class CefContext : public content::NotificationObserver {
|
||||||
|
|
||||||
// Only accessed on the UI Thread.
|
// Only accessed on the UI Thread.
|
||||||
scoped_ptr<content::NotificationRegistrar> registrar_;
|
scoped_ptr<content::NotificationRegistrar> registrar_;
|
||||||
|
scoped_ptr<printing::PrintJobManager> print_job_manager_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper macro that returns true if the global context is in a valid state.
|
// Helper macro that returns true if the global context is in a valid state.
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
// Copyright (c) 2012 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.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "base/bind.h"
|
||||||
|
#include "base/lazy_instance.h"
|
||||||
|
#include "base/metrics/histogram.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/common/print_messages.h"
|
||||||
|
#include "content/public/browser/browser_thread.h"
|
||||||
|
#include "content/public/browser/web_contents.h"
|
||||||
|
#include "printing/print_destination_interface.h"
|
||||||
|
|
||||||
|
using content::BrowserThread;
|
||||||
|
|
||||||
|
DEFINE_WEB_CONTENTS_USER_DATA_KEY(printing::PrintViewManager);
|
||||||
|
|
||||||
|
namespace printing {
|
||||||
|
|
||||||
|
PrintViewManager::PrintViewManager(content::WebContents* web_contents)
|
||||||
|
: PrintViewManagerBase(web_contents) {
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintViewManager::~PrintViewManager() {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PrintViewManager::PrintForSystemDialogNow() {
|
||||||
|
return PrintNowInternal(new PrintMsg_PrintForSystemDialog(routing_id()));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PrintViewManager::PrintToDestination() {
|
||||||
|
// TODO(mad): Remove this once we can send user metrics from the metro driver.
|
||||||
|
// crbug.com/142330
|
||||||
|
UMA_HISTOGRAM_ENUMERATION("Metro.Print", 0, 2);
|
||||||
|
// TODO(mad): Use a passed in destination interface instead.
|
||||||
|
g_browser_process->print_job_manager()->queue()->SetDestination(
|
||||||
|
printing::CreatePrintDestination());
|
||||||
|
return PrintNowInternal(new PrintMsg_PrintPages(routing_id()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintViewManager::RenderProcessGone(base::TerminationStatus status) {
|
||||||
|
PrintViewManagerBase::RenderProcessGone(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintViewManager::OnDidShowPrintDialog() {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PrintViewManager::OnMessageReceived(const IPC::Message& message) {
|
||||||
|
bool handled = true;
|
||||||
|
IPC_BEGIN_MESSAGE_MAP(PrintViewManager, message)
|
||||||
|
IPC_MESSAGE_HANDLER(PrintHostMsg_DidShowPrintDialog, OnDidShowPrintDialog)
|
||||||
|
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||||
|
IPC_END_MESSAGE_MAP()
|
||||||
|
|
||||||
|
return handled ? true : PrintViewManagerBase::OnMessageReceived(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace printing
|
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright (c) 2012 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_H_
|
||||||
|
#define CEF_LIBCEF_BROWSER_PRINTING_PRINT_VIEW_MANAGER_H_
|
||||||
|
|
||||||
|
#include "libcef/browser/printing/print_view_manager_base.h"
|
||||||
|
#include "content/public/browser/web_contents_user_data.h"
|
||||||
|
|
||||||
|
namespace content {
|
||||||
|
class RenderProcessHost;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace printing {
|
||||||
|
|
||||||
|
// Manages the print commands for a WebContents.
|
||||||
|
class PrintViewManager : public PrintViewManagerBase,
|
||||||
|
public content::WebContentsUserData<PrintViewManager> {
|
||||||
|
public:
|
||||||
|
virtual ~PrintViewManager();
|
||||||
|
|
||||||
|
// Same as PrintNow(), but for the case where a user prints with the system
|
||||||
|
// dialog from print preview.
|
||||||
|
bool PrintForSystemDialogNow();
|
||||||
|
|
||||||
|
// Same as PrintNow(), but for the case where we want to send the result to
|
||||||
|
// another destination.
|
||||||
|
// TODO(mad) Add an argument so we can pass the destination interface.
|
||||||
|
bool PrintToDestination();
|
||||||
|
|
||||||
|
// content::WebContentsObserver implementation.
|
||||||
|
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
|
||||||
|
|
||||||
|
// content::WebContentsObserver implementation.
|
||||||
|
// Terminates or cancels the print job if one was pending.
|
||||||
|
virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit PrintViewManager(content::WebContents* web_contents);
|
||||||
|
friend class content::WebContentsUserData<PrintViewManager>;
|
||||||
|
|
||||||
|
// IPC Message handlers.
|
||||||
|
void OnDidShowPrintDialog();
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(PrintViewManager);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace printing
|
||||||
|
|
||||||
|
#endif // CEF_LIBCEF_BROWSER_PRINTING_PRINT_VIEW_MANAGER_H_
|
|
@ -0,0 +1,522 @@
|
||||||
|
// 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 <map>
|
||||||
|
|
||||||
|
#include "libcef/browser/content_browser_client.h"
|
||||||
|
|
||||||
|
#include "base/bind.h"
|
||||||
|
#include "base/memory/scoped_ptr.h"
|
||||||
|
#include "base/prefs/pref_service.h"
|
||||||
|
#include "base/strings/utf_string_conversions.h"
|
||||||
|
#include "base/timer/timer.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/common/pref_names.h"
|
||||||
|
#include "chrome/common/print_messages.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_view_host.h"
|
||||||
|
#include "content/public/browser/web_contents.h"
|
||||||
|
#include "content/public/browser/web_contents_view.h"
|
||||||
|
#include "grit/generated_resources.h"
|
||||||
|
#include "printing/metafile_impl.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_switches.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using base::TimeDelta;
|
||||||
|
using content::BrowserThread;
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
// Limits memory usage by raster to 64 MiB.
|
||||||
|
const int kMaxRasterSizeInPixels = 16*1024*1024;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace printing {
|
||||||
|
|
||||||
|
PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents)
|
||||||
|
: content::WebContentsObserver(web_contents),
|
||||||
|
number_pages_(0),
|
||||||
|
printing_succeeded_(false),
|
||||||
|
inside_inner_message_loop_(false),
|
||||||
|
cookie_(0),
|
||||||
|
queue_(g_browser_process->print_job_manager()->queue()) {
|
||||||
|
DCHECK(queue_);
|
||||||
|
#if defined(OS_POSIX) && !defined(OS_MACOSX)
|
||||||
|
expecting_first_page_ = true;
|
||||||
|
#endif
|
||||||
|
printing_enabled_.Init(
|
||||||
|
prefs::kPrintingEnabled,
|
||||||
|
CefContentBrowserClient::Get()->pref_service(),
|
||||||
|
base::Bind(&PrintViewManagerBase::UpdateScriptedPrintingBlocked,
|
||||||
|
base::Unretained(this)));
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintViewManagerBase::~PrintViewManagerBase() {
|
||||||
|
ReleasePrinterQuery();
|
||||||
|
DisconnectFromCurrentPrintJob();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PrintViewManagerBase::PrintNow() {
|
||||||
|
return PrintNowInternal(new PrintMsg_PrintPages(routing_id()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintViewManagerBase::UpdateScriptedPrintingBlocked() {
|
||||||
|
Send(new PrintMsg_SetScriptedPrintingBlocked(
|
||||||
|
routing_id(),
|
||||||
|
!printing_enabled_.GetValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintViewManagerBase::NavigationStopped() {
|
||||||
|
// Cancel the current job, wait for the worker to finish.
|
||||||
|
TerminatePrintJob(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintViewManagerBase::RenderProcessGone(base::TerminationStatus status) {
|
||||||
|
ReleasePrinterQuery();
|
||||||
|
|
||||||
|
if (!print_job_.get())
|
||||||
|
return;
|
||||||
|
|
||||||
|
scoped_refptr<PrintedDocument> document(print_job_->document());
|
||||||
|
if (document.get()) {
|
||||||
|
// 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string16 PrintViewManagerBase::RenderSourceName() {
|
||||||
|
string16 name(web_contents()->GetTitle());
|
||||||
|
if (name.empty())
|
||||||
|
name = l10n_util::GetStringUTF16(IDS_DEFAULT_PRINT_DOCUMENT_TITLE);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintViewManagerBase::OnDidGetPrintedPagesCount(int cookie,
|
||||||
|
int number_pages) {
|
||||||
|
DCHECK_GT(cookie, 0);
|
||||||
|
DCHECK_GT(number_pages, 0);
|
||||||
|
number_pages_ = number_pages;
|
||||||
|
OpportunisticallyCreatePrintJob(cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintViewManagerBase::OnDidGetDocumentCookie(int cookie) {
|
||||||
|
cookie_ = cookie;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintViewManagerBase::OnDidPrintPage(
|
||||||
|
const PrintHostMsg_DidPrintPage_Params& params) {
|
||||||
|
if (!OpportunisticallyCreatePrintJob(params.document_cookie))
|
||||||
|
return;
|
||||||
|
|
||||||
|
PrintedDocument* document = print_job_->document();
|
||||||
|
if (!document || params.document_cookie != document->cookie()) {
|
||||||
|
// Out of sync. It may happen since we are completely asynchronous. Old
|
||||||
|
// spurious messages can be received if one of the processes is overloaded.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||||
|
const bool metafile_must_be_valid = true;
|
||||||
|
#elif defined(OS_POSIX)
|
||||||
|
const bool metafile_must_be_valid = expecting_first_page_;
|
||||||
|
expecting_first_page_ = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
base::SharedMemory shared_buf(params.metafile_data_handle, true);
|
||||||
|
if (metafile_must_be_valid) {
|
||||||
|
if (!shared_buf.Map(params.data_size)) {
|
||||||
|
NOTREACHED() << "couldn't map";
|
||||||
|
web_contents()->Stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scoped_ptr<NativeMetafile> metafile(new NativeMetafile);
|
||||||
|
if (metafile_must_be_valid) {
|
||||||
|
if (!metafile->InitFromData(shared_buf.memory(), params.data_size)) {
|
||||||
|
NOTREACHED() << "Invalid metafile header";
|
||||||
|
web_contents()->Stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
bool big_emf = (params.data_size && params.data_size >= kMetafileMaxSize);
|
||||||
|
const CommandLine* cmdline = CommandLine::ForCurrentProcess();
|
||||||
|
int raster_size = std::min(params.page_size.GetArea(),
|
||||||
|
kMaxRasterSizeInPixels);
|
||||||
|
if (big_emf || (cmdline && cmdline->HasSwitch(switches::kPrintRaster))) {
|
||||||
|
scoped_ptr<NativeMetafile> raster_metafile(
|
||||||
|
metafile->RasterizeMetafile(raster_size));
|
||||||
|
if (raster_metafile.get()) {
|
||||||
|
metafile.swap(raster_metafile);
|
||||||
|
} else if (big_emf) {
|
||||||
|
// Don't fall back to emf here.
|
||||||
|
NOTREACHED() << "size:" << params.data_size;
|
||||||
|
TerminatePrintJob(true);
|
||||||
|
web_contents()->Stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Update the rendered document. It will send notifications to the listener.
|
||||||
|
document->SetPage(params.page_number,
|
||||||
|
metafile.release(),
|
||||||
|
params.actual_shrink,
|
||||||
|
params.page_size,
|
||||||
|
params.content_area);
|
||||||
|
|
||||||
|
ShouldQuitFromInnerMessageLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintViewManagerBase::OnPrintingFailed(int cookie) {
|
||||||
|
if (cookie != cookie_) {
|
||||||
|
NOTREACHED();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleasePrinterQuery();
|
||||||
|
|
||||||
|
content::NotificationService::current()->Notify(
|
||||||
|
chrome::NOTIFICATION_PRINT_JOB_RELEASED,
|
||||||
|
content::Source<content::WebContents>(web_contents()),
|
||||||
|
content::NotificationService::NoDetails());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintViewManagerBase::DidStartLoading(
|
||||||
|
content::RenderViewHost* render_view_host) {
|
||||||
|
UpdateScriptedPrintingBlocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PrintViewManagerBase::OnMessageReceived(const IPC::Message& message) {
|
||||||
|
bool handled = true;
|
||||||
|
IPC_BEGIN_MESSAGE_MAP(PrintViewManagerBase, message)
|
||||||
|
IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPrintedPagesCount,
|
||||||
|
OnDidGetPrintedPagesCount)
|
||||||
|
IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetDocumentCookie,
|
||||||
|
OnDidGetDocumentCookie)
|
||||||
|
IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintPage, OnDidPrintPage)
|
||||||
|
IPC_MESSAGE_HANDLER(PrintHostMsg_PrintingFailed, OnPrintingFailed)
|
||||||
|
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||||
|
IPC_END_MESSAGE_MAP()
|
||||||
|
return handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintViewManagerBase::Observe(
|
||||||
|
int type,
|
||||||
|
const content::NotificationSource& source,
|
||||||
|
const content::NotificationDetails& details) {
|
||||||
|
switch (type) {
|
||||||
|
case chrome::NOTIFICATION_PRINT_JOB_EVENT: {
|
||||||
|
OnNotifyPrintJobEvent(*content::Details<JobEventDetails>(details).ptr());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
NOTREACHED();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintViewManagerBase::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;
|
||||||
|
}
|
||||||
|
case JobEventDetails::NEW_DOC:
|
||||||
|
case JobEventDetails::NEW_PAGE:
|
||||||
|
case JobEventDetails::PAGE_DONE:
|
||||||
|
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 PrintViewManagerBase::RenderAllMissingPagesNow() {
|
||||||
|
if (!print_job_.get() || !print_job_->is_job_pending())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// We can't print if there is no renderer.
|
||||||
|
if (!web_contents() ||
|
||||||
|
!web_contents()->GetRenderViewHost() ||
|
||||||
|
!web_contents()->GetRenderViewHost()->IsRenderViewLive()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is the document already complete?
|
||||||
|
if (print_job_->document() && print_job_->document()->IsComplete()) {
|
||||||
|
printing_succeeded_ = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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. MessageLoop::current()->Quit() will be called as soon as
|
||||||
|
// print_job_->document()->IsComplete() is true on either ALL_PAGES_REQUESTED
|
||||||
|
// or in DidPrintPage(). 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 PrintViewManagerBase::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::MessageLoop::current()->Quit();
|
||||||
|
inside_inner_message_loop_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PrintViewManagerBase::CreateNewPrintJob(PrintJobWorkerOwner* job) {
|
||||||
|
DCHECK(!inside_inner_message_loop_);
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ask the renderer to generate the print preview, create the print preview
|
||||||
|
// view and switch to it, initialize the printer and show the print dialog.
|
||||||
|
DCHECK(!print_job_.get());
|
||||||
|
DCHECK(job);
|
||||||
|
if (!job)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
print_job_ = new PrintJob();
|
||||||
|
print_job_->Initialize(job, this, number_pages_);
|
||||||
|
registrar_.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
|
||||||
|
content::Source<PrintJob>(print_job_.get()));
|
||||||
|
printing_succeeded_ = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintViewManagerBase::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_.get() &&
|
||||||
|
print_job_->document() &&
|
||||||
|
!print_job_->document()->IsComplete()) {
|
||||||
|
DCHECK(!result);
|
||||||
|
// That failed.
|
||||||
|
TerminatePrintJob(true);
|
||||||
|
} else {
|
||||||
|
// DO NOT wait for the job to finish.
|
||||||
|
ReleasePrintJob();
|
||||||
|
}
|
||||||
|
#if defined(OS_POSIX) && !defined(OS_MACOSX)
|
||||||
|
expecting_first_page_ = true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintViewManagerBase::PrintingDone(bool success) {
|
||||||
|
if (!print_job_.get())
|
||||||
|
return;
|
||||||
|
Send(new PrintMsg_PrintingDone(routing_id(), success));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintViewManagerBase::TerminatePrintJob(bool cancel) {
|
||||||
|
if (!print_job_.get())
|
||||||
|
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 PrintViewManagerBase::ReleasePrintJob() {
|
||||||
|
if (!print_job_.get())
|
||||||
|
return;
|
||||||
|
|
||||||
|
PrintingDone(printing_succeeded_);
|
||||||
|
|
||||||
|
registrar_.Remove(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
|
||||||
|
content::Source<PrintJob>(print_job_.get()));
|
||||||
|
print_job_->DisconnectSource();
|
||||||
|
// Don't close the worker thread.
|
||||||
|
print_job_ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PrintViewManagerBase::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 const int kPrinterSettingsTimeout = 60000;
|
||||||
|
base::OneShotTimer<base::MessageLoop> quit_timer;
|
||||||
|
quit_timer.Start(FROM_HERE,
|
||||||
|
TimeDelta::FromMilliseconds(kPrinterSettingsTimeout),
|
||||||
|
base::MessageLoop::current(), &base::MessageLoop::Quit);
|
||||||
|
|
||||||
|
inside_inner_message_loop_ = true;
|
||||||
|
|
||||||
|
// Need to enable recursive task.
|
||||||
|
{
|
||||||
|
base::MessageLoop::ScopedNestableTaskAllower allow(
|
||||||
|
base::MessageLoop::current());
|
||||||
|
base::MessageLoop::current()->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 PrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) {
|
||||||
|
if (print_job_.get())
|
||||||
|
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)) {
|
||||||
|
// 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 PrintViewManagerBase::PrintNowInternal(IPC::Message* message) {
|
||||||
|
// Don't print / print preview interstitials.
|
||||||
|
if (web_contents()->ShowingInterstitialPage()) {
|
||||||
|
delete message;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Send(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintViewManagerBase::ReleasePrinterQuery() {
|
||||||
|
if (!cookie_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int cookie = cookie_;
|
||||||
|
cookie_ = 0;
|
||||||
|
queue_->SetDestination(NULL);
|
||||||
|
|
||||||
|
|
||||||
|
printing::PrintJobManager* print_job_manager =
|
||||||
|
g_browser_process->print_job_manager();
|
||||||
|
// May be NULL in tests.
|
||||||
|
if (!print_job_manager)
|
||||||
|
return;
|
||||||
|
|
||||||
|
scoped_refptr<printing::PrinterQuery> printer_query;
|
||||||
|
printer_query = queue_->PopPrinterQuery(cookie);
|
||||||
|
if (!printer_query)
|
||||||
|
return;
|
||||||
|
BrowserThread::PostTask(
|
||||||
|
BrowserThread::IO, FROM_HERE,
|
||||||
|
base::Bind(&PrinterQuery::StopWorker, printer_query.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace printing
|
|
@ -0,0 +1,166 @@
|
||||||
|
// 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 "base/memory/ref_counted.h"
|
||||||
|
#include "base/prefs/pref_member.h"
|
||||||
|
#include "base/strings/string16.h"
|
||||||
|
#include "content/public/browser/notification_observer.h"
|
||||||
|
#include "content/public/browser/notification_registrar.h"
|
||||||
|
#include "content/public/browser/web_contents_observer.h"
|
||||||
|
#include "content/public/browser/web_contents_user_data.h"
|
||||||
|
#include "printing/printed_pages_source.h"
|
||||||
|
|
||||||
|
struct PrintHostMsg_DidPrintPage_Params;
|
||||||
|
|
||||||
|
namespace content {
|
||||||
|
class RenderViewHost;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace printing {
|
||||||
|
|
||||||
|
class JobEventDetails;
|
||||||
|
class PrintJob;
|
||||||
|
class PrintJobWorkerOwner;
|
||||||
|
class PrintQueriesQueue;
|
||||||
|
|
||||||
|
// Base class for managing the print commands for a WebContents.
|
||||||
|
class PrintViewManagerBase : public content::NotificationObserver,
|
||||||
|
public PrintedPagesSource,
|
||||||
|
public content::WebContentsObserver {
|
||||||
|
public:
|
||||||
|
virtual ~PrintViewManagerBase();
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
// Whether to block scripted printing for our tab or not.
|
||||||
|
void UpdateScriptedPrintingBlocked();
|
||||||
|
|
||||||
|
// PrintedPagesSource implementation.
|
||||||
|
virtual string16 RenderSourceName() OVERRIDE;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
explicit PrintViewManagerBase(content::WebContents* web_contents);
|
||||||
|
|
||||||
|
// Helper method for Print*Now().
|
||||||
|
bool PrintNowInternal(IPC::Message* message);
|
||||||
|
|
||||||
|
// Terminates or cancels the print job if one was pending.
|
||||||
|
virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
|
||||||
|
|
||||||
|
// content::WebContentsObserver implementation.
|
||||||
|
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
|
||||||
|
|
||||||
|
// IPC Message handlers.
|
||||||
|
virtual void OnPrintingFailed(int cookie);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// content::NotificationObserver implementation.
|
||||||
|
virtual void Observe(int type,
|
||||||
|
const content::NotificationSource& source,
|
||||||
|
const content::NotificationDetails& details) OVERRIDE;
|
||||||
|
|
||||||
|
// content::WebContentsObserver implementation.
|
||||||
|
virtual void DidStartLoading(
|
||||||
|
content::RenderViewHost* render_view_host) OVERRIDE;
|
||||||
|
|
||||||
|
// Cancels the print job.
|
||||||
|
virtual void NavigationStopped() OVERRIDE;
|
||||||
|
|
||||||
|
// IPC Message handlers.
|
||||||
|
void OnDidGetPrintedPagesCount(int cookie, int number_pages);
|
||||||
|
void OnDidGetDocumentCookie(int cookie);
|
||||||
|
void OnDidPrintPage(const PrintHostMsg_DidPrintPage_Params& params);
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
// 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 DidPrintPage() or on ALL_PAGES_REQUESTED
|
||||||
|
// notification. The inner message loop is created was created by
|
||||||
|
// RenderAllMissingPagesNow().
|
||||||
|
void ShouldQuitFromInnerMessageLoop();
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
bool CreateNewPrintJob(PrintJobWorkerOwner* job);
|
||||||
|
|
||||||
|
// Makes sure the current print_job_ has all its data before continuing, and
|
||||||
|
// disconnect from it.
|
||||||
|
void DisconnectFromCurrentPrintJob();
|
||||||
|
|
||||||
|
// Notify that the printing is done.
|
||||||
|
void PrintingDone(bool success);
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
content::NotificationRegistrar registrar_;
|
||||||
|
|
||||||
|
// Manages the low-level talk to the printer.
|
||||||
|
scoped_refptr<PrintJob> print_job_;
|
||||||
|
|
||||||
|
// Number of pages to print in the print job.
|
||||||
|
int number_pages_;
|
||||||
|
|
||||||
|
// 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_;
|
||||||
|
|
||||||
|
#if defined(OS_POSIX) && !defined(OS_MACOSX)
|
||||||
|
// Set to true when OnDidPrintPage() should be expecting the first page.
|
||||||
|
bool expecting_first_page_;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// The document cookie of the current PrinterQuery.
|
||||||
|
int cookie_;
|
||||||
|
|
||||||
|
// Whether printing is enabled.
|
||||||
|
BooleanPrefMember printing_enabled_;
|
||||||
|
|
||||||
|
scoped_refptr<printing::PrintQueriesQueue> queue_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(PrintViewManagerBase);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace printing
|
||||||
|
|
||||||
|
#endif // CEF_LIBCEF_BROWSER_PRINTING_PRINT_VIEW_MANAGER_BASE_H_
|
|
@ -0,0 +1,446 @@
|
||||||
|
// Copyright (c) 2012 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/printing_message_filter.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "base/bind.h"
|
||||||
|
#include "chrome/browser/browser_process.h"
|
||||||
|
#include "chrome/browser/printing/printer_query.h"
|
||||||
|
#include "chrome/browser/printing/print_job_manager.h"
|
||||||
|
#include "chrome/common/print_messages.h"
|
||||||
|
#include "content/public/browser/browser_thread.h"
|
||||||
|
#include "content/public/browser/render_view_host.h"
|
||||||
|
#include "content/public/browser/web_contents.h"
|
||||||
|
#include "content/public/browser/web_contents_view.h"
|
||||||
|
|
||||||
|
#if defined(OS_CHROMEOS)
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "base/file_util.h"
|
||||||
|
#include "base/lazy_instance.h"
|
||||||
|
#include "chrome/browser/printing/print_dialog_cloud.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(OS_ANDROID)
|
||||||
|
#include "base/strings/string_number_conversions.h"
|
||||||
|
#include "chrome/browser/printing/print_view_manager_basic.h"
|
||||||
|
#include "printing/printing_context_android.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using content::BrowserThread;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
#if defined(OS_CHROMEOS)
|
||||||
|
typedef std::map<int, base::FilePath> SequenceToPathMap;
|
||||||
|
|
||||||
|
struct PrintingSequencePathMap {
|
||||||
|
SequenceToPathMap map;
|
||||||
|
int sequence;
|
||||||
|
};
|
||||||
|
|
||||||
|
// No locking, only access on the FILE thread.
|
||||||
|
static base::LazyInstance<PrintingSequencePathMap>
|
||||||
|
g_printing_file_descriptor_map = LAZY_INSTANCE_INITIALIZER;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void RenderParamsFromPrintSettings(const printing::PrintSettings& settings,
|
||||||
|
PrintMsg_Print_Params* params) {
|
||||||
|
params->page_size = settings.page_setup_device_units().physical_size();
|
||||||
|
params->content_size.SetSize(
|
||||||
|
settings.page_setup_device_units().content_area().width(),
|
||||||
|
settings.page_setup_device_units().content_area().height());
|
||||||
|
params->printable_area.SetRect(
|
||||||
|
settings.page_setup_device_units().printable_area().x(),
|
||||||
|
settings.page_setup_device_units().printable_area().y(),
|
||||||
|
settings.page_setup_device_units().printable_area().width(),
|
||||||
|
settings.page_setup_device_units().printable_area().height());
|
||||||
|
params->margin_top = settings.page_setup_device_units().content_area().y();
|
||||||
|
params->margin_left = settings.page_setup_device_units().content_area().x();
|
||||||
|
params->dpi = settings.dpi();
|
||||||
|
// Currently hardcoded at 1.25. See PrintSettings' constructor.
|
||||||
|
params->min_shrink = settings.min_shrink;
|
||||||
|
// Currently hardcoded at 2.0. See PrintSettings' constructor.
|
||||||
|
params->max_shrink = settings.max_shrink;
|
||||||
|
// Currently hardcoded at 72dpi. See PrintSettings' constructor.
|
||||||
|
params->desired_dpi = settings.desired_dpi;
|
||||||
|
// Always use an invalid cookie.
|
||||||
|
params->document_cookie = 0;
|
||||||
|
params->selection_only = settings.selection_only;
|
||||||
|
params->supports_alpha_blend = settings.supports_alpha_blend();
|
||||||
|
params->should_print_backgrounds = settings.should_print_backgrounds;
|
||||||
|
params->display_header_footer = settings.display_header_footer;
|
||||||
|
params->date = settings.date;
|
||||||
|
params->title = settings.title;
|
||||||
|
params->url = settings.url;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
PrintingMessageFilter::PrintingMessageFilter(int render_process_id)
|
||||||
|
: render_process_id_(render_process_id),
|
||||||
|
queue_(g_browser_process->print_job_manager()->queue()) {
|
||||||
|
DCHECK(queue_);
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintingMessageFilter::~PrintingMessageFilter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintingMessageFilter::OverrideThreadForMessage(
|
||||||
|
const IPC::Message& message, BrowserThread::ID* thread) {
|
||||||
|
#if defined(OS_CHROMEOS)
|
||||||
|
if (message.type() == PrintHostMsg_AllocateTempFileForPrinting::ID ||
|
||||||
|
message.type() == PrintHostMsg_TempFileForPrintingWritten::ID) {
|
||||||
|
*thread = BrowserThread::FILE;
|
||||||
|
}
|
||||||
|
#elif defined(OS_ANDROID)
|
||||||
|
if (message.type() == PrintHostMsg_AllocateTempFileForPrinting::ID ||
|
||||||
|
message.type() == PrintHostMsg_TempFileForPrintingWritten::ID) {
|
||||||
|
*thread = BrowserThread::UI;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PrintingMessageFilter::OnMessageReceived(const IPC::Message& message,
|
||||||
|
bool* message_was_ok) {
|
||||||
|
bool handled = true;
|
||||||
|
IPC_BEGIN_MESSAGE_MAP_EX(PrintingMessageFilter, message, *message_was_ok)
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
IPC_MESSAGE_HANDLER(PrintHostMsg_DuplicateSection, OnDuplicateSection)
|
||||||
|
#endif
|
||||||
|
#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
|
||||||
|
IPC_MESSAGE_HANDLER(PrintHostMsg_AllocateTempFileForPrinting,
|
||||||
|
OnAllocateTempFileForPrinting)
|
||||||
|
IPC_MESSAGE_HANDLER(PrintHostMsg_TempFileForPrintingWritten,
|
||||||
|
OnTempFileForPrintingWritten)
|
||||||
|
#endif
|
||||||
|
IPC_MESSAGE_HANDLER(PrintHostMsg_IsPrintingEnabled, OnIsPrintingEnabled)
|
||||||
|
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_GetDefaultPrintSettings,
|
||||||
|
OnGetDefaultPrintSettings)
|
||||||
|
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_ScriptedPrint, OnScriptedPrint)
|
||||||
|
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_UpdatePrintSettings,
|
||||||
|
OnUpdatePrintSettings)
|
||||||
|
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||||
|
IPC_END_MESSAGE_MAP()
|
||||||
|
return handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
void PrintingMessageFilter::OnDuplicateSection(
|
||||||
|
base::SharedMemoryHandle renderer_handle,
|
||||||
|
base::SharedMemoryHandle* browser_handle) {
|
||||||
|
// Duplicate the handle in this process right now so the memory is kept alive
|
||||||
|
// (even if it is not mapped)
|
||||||
|
base::SharedMemory shared_buf(renderer_handle, true, PeerHandle());
|
||||||
|
shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), browser_handle);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
|
||||||
|
void PrintingMessageFilter::OnAllocateTempFileForPrinting(
|
||||||
|
int render_view_id,
|
||||||
|
base::FileDescriptor* temp_file_fd,
|
||||||
|
int* sequence_number) {
|
||||||
|
#if defined(OS_CHROMEOS)
|
||||||
|
// TODO(thestig): Use |render_view_id| for Chrome OS.
|
||||||
|
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
||||||
|
temp_file_fd->fd = *sequence_number = -1;
|
||||||
|
temp_file_fd->auto_close = false;
|
||||||
|
|
||||||
|
SequenceToPathMap* map = &g_printing_file_descriptor_map.Get().map;
|
||||||
|
*sequence_number = g_printing_file_descriptor_map.Get().sequence++;
|
||||||
|
|
||||||
|
base::FilePath path;
|
||||||
|
if (file_util::CreateTemporaryFile(&path)) {
|
||||||
|
int fd = open(path.value().c_str(), O_WRONLY);
|
||||||
|
if (fd >= 0) {
|
||||||
|
SequenceToPathMap::iterator it = map->find(*sequence_number);
|
||||||
|
if (it != map->end()) {
|
||||||
|
NOTREACHED() << "Sequence number already in use. seq=" <<
|
||||||
|
*sequence_number;
|
||||||
|
} else {
|
||||||
|
(*map)[*sequence_number] = path;
|
||||||
|
temp_file_fd->fd = fd;
|
||||||
|
temp_file_fd->auto_close = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif defined(OS_ANDROID)
|
||||||
|
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||||
|
content::WebContents* wc = GetWebContentsForRenderView(render_view_id);
|
||||||
|
if (!wc)
|
||||||
|
return;
|
||||||
|
printing::PrintViewManagerBasic* print_view_manager =
|
||||||
|
printing::PrintViewManagerBasic::FromWebContents(wc);
|
||||||
|
// The file descriptor is originally created in & passed from the Android
|
||||||
|
// side, and it will handle the closing.
|
||||||
|
const base::FileDescriptor& file_descriptor =
|
||||||
|
print_view_manager->file_descriptor();
|
||||||
|
temp_file_fd->fd = file_descriptor.fd;
|
||||||
|
temp_file_fd->auto_close = false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintingMessageFilter::OnTempFileForPrintingWritten(int render_view_id,
|
||||||
|
int sequence_number) {
|
||||||
|
#if defined(OS_CHROMEOS)
|
||||||
|
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
||||||
|
SequenceToPathMap* map = &g_printing_file_descriptor_map.Get().map;
|
||||||
|
SequenceToPathMap::iterator it = map->find(sequence_number);
|
||||||
|
if (it == map->end()) {
|
||||||
|
NOTREACHED() << "Got a sequence that we didn't pass to the "
|
||||||
|
"renderer: " << sequence_number;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BrowserThread::PostTask(
|
||||||
|
BrowserThread::UI, FROM_HERE,
|
||||||
|
base::Bind(&PrintingMessageFilter::CreatePrintDialogForFile,
|
||||||
|
this, render_view_id, it->second));
|
||||||
|
|
||||||
|
// Erase the entry in the map.
|
||||||
|
map->erase(it);
|
||||||
|
#elif defined(OS_ANDROID)
|
||||||
|
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||||
|
content::WebContents* wc = GetWebContentsForRenderView(render_view_id);
|
||||||
|
if (!wc)
|
||||||
|
return;
|
||||||
|
printing::PrintViewManagerBasic* print_view_manager =
|
||||||
|
printing::PrintViewManagerBasic::FromWebContents(wc);
|
||||||
|
const base::FileDescriptor& file_descriptor =
|
||||||
|
print_view_manager->file_descriptor();
|
||||||
|
printing::PrintingContextAndroid::PdfWritingDone(file_descriptor.fd, true);
|
||||||
|
// Invalidate the file descriptor so it doesn't accidentally get reused.
|
||||||
|
print_view_manager->set_file_descriptor(base::FileDescriptor(-1, false));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif // defined(OS_CHROMEOS) || defined(OS_ANDROID)
|
||||||
|
|
||||||
|
#if defined(OS_CHROMEOS)
|
||||||
|
void PrintingMessageFilter::CreatePrintDialogForFile(
|
||||||
|
int render_view_id,
|
||||||
|
const base::FilePath& path) {
|
||||||
|
content::WebContents* wc = GetWebContentsForRenderView(render_view_id);
|
||||||
|
if (!wc)
|
||||||
|
return;
|
||||||
|
print_dialog_cloud::CreatePrintDialogForFile(
|
||||||
|
wc->GetBrowserContext(),
|
||||||
|
wc->GetView()->GetTopLevelNativeWindow(),
|
||||||
|
path,
|
||||||
|
wc->GetTitle(),
|
||||||
|
string16(),
|
||||||
|
std::string("application/pdf"),
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
#endif // defined(OS_CHROMEOS)
|
||||||
|
|
||||||
|
content::WebContents* PrintingMessageFilter::GetWebContentsForRenderView(
|
||||||
|
int render_view_id) {
|
||||||
|
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||||
|
content::RenderViewHost* view = content::RenderViewHost::FromID(
|
||||||
|
render_process_id_, render_view_id);
|
||||||
|
return view ? content::WebContents::FromRenderViewHost(view) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PrintingMessageFilter::GetPrintSettingsForRenderViewParams {
|
||||||
|
printing::PrinterQuery::GetSettingsAskParam ask_user_for_settings;
|
||||||
|
int expected_page_count;
|
||||||
|
bool has_selection;
|
||||||
|
printing::MarginType margin_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
void PrintingMessageFilter::GetPrintSettingsForRenderView(
|
||||||
|
int render_view_id,
|
||||||
|
GetPrintSettingsForRenderViewParams params,
|
||||||
|
const base::Closure& callback,
|
||||||
|
scoped_refptr<printing::PrinterQuery> printer_query) {
|
||||||
|
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||||
|
content::WebContents* wc = GetWebContentsForRenderView(render_view_id);
|
||||||
|
if (wc) {
|
||||||
|
BrowserThread::PostTask(
|
||||||
|
BrowserThread::IO, FROM_HERE,
|
||||||
|
base::Bind(&printing::PrinterQuery::GetSettings, printer_query,
|
||||||
|
params.ask_user_for_settings, wc->GetView()->GetNativeView(),
|
||||||
|
params.expected_page_count, params.has_selection,
|
||||||
|
params.margin_type, callback));
|
||||||
|
} else {
|
||||||
|
BrowserThread::PostTask(
|
||||||
|
BrowserThread::IO, FROM_HERE,
|
||||||
|
base::Bind(&PrintingMessageFilter::OnGetPrintSettingsFailed, this,
|
||||||
|
callback, printer_query));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintingMessageFilter::OnGetPrintSettingsFailed(
|
||||||
|
const base::Closure& callback,
|
||||||
|
scoped_refptr<printing::PrinterQuery> printer_query) {
|
||||||
|
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
||||||
|
printer_query->GetSettingsDone(printing::PrintSettings(),
|
||||||
|
printing::PrintingContext::FAILED);
|
||||||
|
callback.Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintingMessageFilter::OnIsPrintingEnabled(bool* is_enabled) {
|
||||||
|
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
||||||
|
*is_enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintingMessageFilter::OnGetDefaultPrintSettings(IPC::Message* reply_msg) {
|
||||||
|
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
||||||
|
scoped_refptr<printing::PrinterQuery> printer_query;
|
||||||
|
printer_query = queue_->PopPrinterQuery(0);
|
||||||
|
if (!printer_query)
|
||||||
|
printer_query = queue_->CreatePrinterQuery();
|
||||||
|
|
||||||
|
// Loads default settings. This is asynchronous, only the IPC message sender
|
||||||
|
// will hang until the settings are retrieved.
|
||||||
|
GetPrintSettingsForRenderViewParams params;
|
||||||
|
params.ask_user_for_settings = printing::PrinterQuery::DEFAULTS;
|
||||||
|
params.expected_page_count = 0;
|
||||||
|
params.has_selection = false;
|
||||||
|
params.margin_type = printing::DEFAULT_MARGINS;
|
||||||
|
BrowserThread::PostTask(
|
||||||
|
BrowserThread::UI, FROM_HERE,
|
||||||
|
base::Bind(&PrintingMessageFilter::GetPrintSettingsForRenderView, this,
|
||||||
|
reply_msg->routing_id(), params,
|
||||||
|
base::Bind(&PrintingMessageFilter::OnGetDefaultPrintSettingsReply,
|
||||||
|
this, printer_query, reply_msg),
|
||||||
|
printer_query));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintingMessageFilter::OnGetDefaultPrintSettingsReply(
|
||||||
|
scoped_refptr<printing::PrinterQuery> printer_query,
|
||||||
|
IPC::Message* reply_msg) {
|
||||||
|
PrintMsg_Print_Params params;
|
||||||
|
if (!printer_query.get() ||
|
||||||
|
printer_query->last_status() != printing::PrintingContext::OK) {
|
||||||
|
params.Reset();
|
||||||
|
} else {
|
||||||
|
RenderParamsFromPrintSettings(printer_query->settings(), ¶ms);
|
||||||
|
params.document_cookie = printer_query->cookie();
|
||||||
|
}
|
||||||
|
PrintHostMsg_GetDefaultPrintSettings::WriteReplyParams(reply_msg, params);
|
||||||
|
Send(reply_msg);
|
||||||
|
// If printing was enabled.
|
||||||
|
if (printer_query.get()) {
|
||||||
|
// If user hasn't cancelled.
|
||||||
|
if (printer_query->cookie() && printer_query->settings().dpi()) {
|
||||||
|
queue_->QueuePrinterQuery(printer_query.get());
|
||||||
|
} else {
|
||||||
|
printer_query->StopWorker();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintingMessageFilter::OnScriptedPrint(
|
||||||
|
const PrintHostMsg_ScriptedPrint_Params& params,
|
||||||
|
IPC::Message* reply_msg) {
|
||||||
|
scoped_refptr<printing::PrinterQuery> printer_query =
|
||||||
|
queue_->PopPrinterQuery(params.cookie);
|
||||||
|
if (!printer_query)
|
||||||
|
printer_query = queue_->CreatePrinterQuery();
|
||||||
|
GetPrintSettingsForRenderViewParams settings_params;
|
||||||
|
settings_params.ask_user_for_settings = printing::PrinterQuery::ASK_USER;
|
||||||
|
settings_params.expected_page_count = params.expected_pages_count;
|
||||||
|
settings_params.has_selection = params.has_selection;
|
||||||
|
settings_params.margin_type = params.margin_type;
|
||||||
|
|
||||||
|
BrowserThread::PostTask(
|
||||||
|
BrowserThread::UI, FROM_HERE,
|
||||||
|
base::Bind(&PrintingMessageFilter::GetPrintSettingsForRenderView, this,
|
||||||
|
reply_msg->routing_id(), settings_params,
|
||||||
|
base::Bind(&PrintingMessageFilter::OnScriptedPrintReply, this,
|
||||||
|
printer_query, reply_msg),
|
||||||
|
printer_query));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintingMessageFilter::OnScriptedPrintReply(
|
||||||
|
scoped_refptr<printing::PrinterQuery> printer_query,
|
||||||
|
IPC::Message* reply_msg) {
|
||||||
|
PrintMsg_PrintPages_Params params;
|
||||||
|
#if defined(OS_ANDROID)
|
||||||
|
// We need to save the routing ID here because Send method below deletes the
|
||||||
|
// |reply_msg| before we can get the routing ID for the Android code.
|
||||||
|
int routing_id = reply_msg->routing_id();
|
||||||
|
#endif
|
||||||
|
if (printer_query->last_status() != printing::PrintingContext::OK ||
|
||||||
|
!printer_query->settings().dpi()) {
|
||||||
|
params.Reset();
|
||||||
|
} else {
|
||||||
|
RenderParamsFromPrintSettings(printer_query->settings(), ¶ms.params);
|
||||||
|
params.params.document_cookie = printer_query->cookie();
|
||||||
|
params.pages =
|
||||||
|
printing::PageRange::GetPages(printer_query->settings().ranges);
|
||||||
|
}
|
||||||
|
PrintHostMsg_ScriptedPrint::WriteReplyParams(reply_msg, params);
|
||||||
|
Send(reply_msg);
|
||||||
|
if (params.params.dpi && params.params.document_cookie) {
|
||||||
|
#if defined(OS_ANDROID)
|
||||||
|
int file_descriptor;
|
||||||
|
const string16& device_name = printer_query->settings().device_name();
|
||||||
|
if (base::StringToInt(device_name, &file_descriptor)) {
|
||||||
|
BrowserThread::PostTask(
|
||||||
|
BrowserThread::UI, FROM_HERE,
|
||||||
|
base::Bind(&PrintingMessageFilter::UpdateFileDescriptor, this,
|
||||||
|
routing_id, file_descriptor));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
queue_->QueuePrinterQuery(printer_query.get());
|
||||||
|
} else {
|
||||||
|
printer_query->StopWorker();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(OS_ANDROID)
|
||||||
|
void PrintingMessageFilter::UpdateFileDescriptor(int render_view_id, int fd) {
|
||||||
|
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||||
|
content::WebContents* wc = GetWebContentsForRenderView(render_view_id);
|
||||||
|
if (!wc)
|
||||||
|
return;
|
||||||
|
printing::PrintViewManagerBasic* print_view_manager =
|
||||||
|
printing::PrintViewManagerBasic::FromWebContents(wc);
|
||||||
|
print_view_manager->set_file_descriptor(base::FileDescriptor(fd, false));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void PrintingMessageFilter::OnUpdatePrintSettings(
|
||||||
|
int document_cookie, const DictionaryValue& job_settings,
|
||||||
|
IPC::Message* reply_msg) {
|
||||||
|
scoped_refptr<printing::PrinterQuery> printer_query;
|
||||||
|
printer_query = queue_->PopPrinterQuery(document_cookie);
|
||||||
|
if (!printer_query)
|
||||||
|
printer_query = queue_->CreatePrinterQuery();
|
||||||
|
printer_query->SetSettings(
|
||||||
|
job_settings,
|
||||||
|
base::Bind(&PrintingMessageFilter::OnUpdatePrintSettingsReply, this,
|
||||||
|
printer_query, reply_msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintingMessageFilter::OnUpdatePrintSettingsReply(
|
||||||
|
scoped_refptr<printing::PrinterQuery> printer_query,
|
||||||
|
IPC::Message* reply_msg) {
|
||||||
|
PrintMsg_PrintPages_Params params;
|
||||||
|
if (!printer_query.get() ||
|
||||||
|
printer_query->last_status() != printing::PrintingContext::OK) {
|
||||||
|
params.Reset();
|
||||||
|
} else {
|
||||||
|
RenderParamsFromPrintSettings(printer_query->settings(), ¶ms.params);
|
||||||
|
params.params.document_cookie = printer_query->cookie();
|
||||||
|
params.pages =
|
||||||
|
printing::PageRange::GetPages(printer_query->settings().ranges);
|
||||||
|
}
|
||||||
|
PrintHostMsg_UpdatePrintSettings::WriteReplyParams(reply_msg, params);
|
||||||
|
Send(reply_msg);
|
||||||
|
// If user hasn't cancelled.
|
||||||
|
if (printer_query.get()) {
|
||||||
|
if (printer_query->cookie() && printer_query->settings().dpi()) {
|
||||||
|
queue_->QueuePrinterQuery(printer_query.get());
|
||||||
|
} else {
|
||||||
|
printer_query->StopWorker();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,132 @@
|
||||||
|
// Copyright (c) 2012 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_PRINTING_MESSAGE_FILTER_H_
|
||||||
|
#define CEF_LIBCEF_BROWSER_PRINTING_PRINTING_MESSAGE_FILTER_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "base/compiler_specific.h"
|
||||||
|
#include "content/public/browser/browser_message_filter.h"
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
#include "base/memory/shared_memory.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct PrintHostMsg_ScriptedPrint_Params;
|
||||||
|
|
||||||
|
namespace base {
|
||||||
|
class DictionaryValue;
|
||||||
|
class FilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace content {
|
||||||
|
class WebContents;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace printing {
|
||||||
|
class PrinterQuery;
|
||||||
|
class PrintJobManager;
|
||||||
|
class PrintQueriesQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This class filters out incoming printing related IPC messages for the
|
||||||
|
// renderer process on the IPC thread.
|
||||||
|
class PrintingMessageFilter : public content::BrowserMessageFilter {
|
||||||
|
public:
|
||||||
|
explicit PrintingMessageFilter(int render_process_id);
|
||||||
|
|
||||||
|
// content::BrowserMessageFilter methods.
|
||||||
|
virtual void OverrideThreadForMessage(
|
||||||
|
const IPC::Message& message,
|
||||||
|
content::BrowserThread::ID* thread) OVERRIDE;
|
||||||
|
virtual bool OnMessageReceived(const IPC::Message& message,
|
||||||
|
bool* message_was_ok) OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual ~PrintingMessageFilter();
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
// Used to pass resulting EMF from renderer to browser in printing.
|
||||||
|
void OnDuplicateSection(base::SharedMemoryHandle renderer_handle,
|
||||||
|
base::SharedMemoryHandle* browser_handle);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
|
||||||
|
// Used to ask the browser allocate a temporary file for the renderer
|
||||||
|
// to fill in resulting PDF in renderer.
|
||||||
|
void OnAllocateTempFileForPrinting(int render_view_id,
|
||||||
|
base::FileDescriptor* temp_file_fd,
|
||||||
|
int* sequence_number);
|
||||||
|
void OnTempFileForPrintingWritten(int render_view_id, int sequence_number);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(OS_CHROMEOS)
|
||||||
|
void CreatePrintDialogForFile(int render_view_id, const base::FilePath& path);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(OS_ANDROID)
|
||||||
|
// Updates the file descriptor for the PrintViewManagerBasic of a given
|
||||||
|
// render_view_id.
|
||||||
|
void UpdateFileDescriptor(int render_view_id, int fd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Given a render_view_id get the corresponding WebContents.
|
||||||
|
// Must be called on the UI thread.
|
||||||
|
content::WebContents* GetWebContentsForRenderView(int render_view_id);
|
||||||
|
|
||||||
|
// GetPrintSettingsForRenderView must be called via PostTask and
|
||||||
|
// base::Bind. Collapse the settings-specific params into a
|
||||||
|
// struct to avoid running into issues with too many params
|
||||||
|
// to base::Bind.
|
||||||
|
struct GetPrintSettingsForRenderViewParams;
|
||||||
|
|
||||||
|
// Retrieve print settings. Uses |render_view_id| to get a parent
|
||||||
|
// for any UI created if needed.
|
||||||
|
void GetPrintSettingsForRenderView(
|
||||||
|
int render_view_id,
|
||||||
|
GetPrintSettingsForRenderViewParams params,
|
||||||
|
const base::Closure& callback,
|
||||||
|
scoped_refptr<printing::PrinterQuery> printer_query);
|
||||||
|
|
||||||
|
void OnGetPrintSettingsFailed(
|
||||||
|
const base::Closure& callback,
|
||||||
|
scoped_refptr<printing::PrinterQuery> printer_query);
|
||||||
|
|
||||||
|
// Checks if printing is enabled.
|
||||||
|
void OnIsPrintingEnabled(bool* is_enabled);
|
||||||
|
|
||||||
|
// Get the default print setting.
|
||||||
|
void OnGetDefaultPrintSettings(IPC::Message* reply_msg);
|
||||||
|
void OnGetDefaultPrintSettingsReply(
|
||||||
|
scoped_refptr<printing::PrinterQuery> printer_query,
|
||||||
|
IPC::Message* reply_msg);
|
||||||
|
|
||||||
|
// The renderer host have to show to the user the print dialog and returns
|
||||||
|
// the selected print settings. The task is handled by the print worker
|
||||||
|
// thread and the UI thread. The reply occurs on the IO thread.
|
||||||
|
void OnScriptedPrint(const PrintHostMsg_ScriptedPrint_Params& params,
|
||||||
|
IPC::Message* reply_msg);
|
||||||
|
void OnScriptedPrintReply(
|
||||||
|
scoped_refptr<printing::PrinterQuery> printer_query,
|
||||||
|
IPC::Message* reply_msg);
|
||||||
|
|
||||||
|
// Modify the current print settings based on |job_settings|. The task is
|
||||||
|
// handled by the print worker thread and the UI thread. The reply occurs on
|
||||||
|
// the IO thread.
|
||||||
|
void OnUpdatePrintSettings(int document_cookie,
|
||||||
|
const base::DictionaryValue& job_settings,
|
||||||
|
IPC::Message* reply_msg);
|
||||||
|
void OnUpdatePrintSettingsReply(
|
||||||
|
scoped_refptr<printing::PrinterQuery> printer_query,
|
||||||
|
IPC::Message* reply_msg);
|
||||||
|
|
||||||
|
const int render_process_id_;
|
||||||
|
|
||||||
|
scoped_refptr<printing::PrintQueriesQueue> queue_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(PrintingMessageFilter);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CEF_LIBCEF_BROWSER_PRINTING_PRINTING_MESSAGE_FILTER_H_
|
|
@ -218,3 +218,6 @@ struct ParamTraits<scoped_refptr<net::UploadData> > {
|
||||||
} // namespace IPC
|
} // namespace IPC
|
||||||
|
|
||||||
#endif // CEF_LIBCEF_COMMON_CEF_MESSAGES_H_
|
#endif // CEF_LIBCEF_COMMON_CEF_MESSAGES_H_
|
||||||
|
|
||||||
|
#include "chrome/common/prerender_messages.h"
|
||||||
|
#include "chrome/common/print_messages.h"
|
||||||
|
|
|
@ -33,6 +33,7 @@ MSVC_POP_WARNING();
|
||||||
#include "base/path_service.h"
|
#include "base/path_service.h"
|
||||||
#include "base/strings/string_number_conversions.h"
|
#include "base/strings/string_number_conversions.h"
|
||||||
#include "chrome/renderer/loadtimes_extension_bindings.h"
|
#include "chrome/renderer/loadtimes_extension_bindings.h"
|
||||||
|
#include "chrome/renderer/printing/print_web_view_helper.h"
|
||||||
#include "content/child/child_thread.h"
|
#include "content/child/child_thread.h"
|
||||||
#include "content/public/browser/browser_thread.h"
|
#include "content/public/browser/browser_thread.h"
|
||||||
#include "content/public/browser/render_process_host.h"
|
#include "content/public/browser/render_process_host.h"
|
||||||
|
@ -443,6 +444,7 @@ void CefContentRendererClient::RenderViewCreated(
|
||||||
browsers_.insert(std::make_pair(render_view, browser));
|
browsers_.insert(std::make_pair(render_view, browser));
|
||||||
|
|
||||||
new CefPrerendererClient(render_view);
|
new CefPrerendererClient(render_view);
|
||||||
|
new printing::PrintWebViewHelper(render_view);
|
||||||
|
|
||||||
// Notify the render process handler.
|
// Notify the render process handler.
|
||||||
CefRefPtr<CefApp> application = CefContentClient::Get()->application();
|
CefRefPtr<CefApp> application = CefContentClient::Get()->application();
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
<include name="IDR_CEF_CREDITS_SWIFTSHADER_JPG" file="..\..\..\chrome\browser\resources\swiftshader.jpg" type="BINDATA" />
|
<include name="IDR_CEF_CREDITS_SWIFTSHADER_JPG" file="..\..\..\chrome\browser\resources\swiftshader.jpg" type="BINDATA" />
|
||||||
<include name="IDR_CEF_LICENSE_TXT" file="..\..\LICENSE.txt" type="BINDATA" />
|
<include name="IDR_CEF_LICENSE_TXT" file="..\..\LICENSE.txt" type="BINDATA" />
|
||||||
<include name="IDR_CEF_VERSION_HTML" file="about_version.html" type="BINDATA" />
|
<include name="IDR_CEF_VERSION_HTML" file="about_version.html" type="BINDATA" />
|
||||||
|
<include name="IDR_PRINT_PREVIEW_PAGE" file="print_preview_page_stub.html" type="BINDATA" />
|
||||||
</includes>
|
</includes>
|
||||||
</release>
|
</release>
|
||||||
</grit>
|
</grit>
|
||||||
|
|
|
@ -263,6 +263,20 @@ need to be translated for each locale.-->
|
||||||
<message name="IDS_APP_VIDEO_FILES" desc="The text label for the Video Files filter in file open/save dialogs.">
|
<message name="IDS_APP_VIDEO_FILES" desc="The text label for the Video Files filter in file open/save dialogs.">
|
||||||
Video Files
|
Video Files
|
||||||
</message>
|
</message>
|
||||||
|
|
||||||
|
<!-- Print -->
|
||||||
|
<message name="IDS_DEFAULT_PRINT_DOCUMENT_TITLE" desc="Default title for a print document">
|
||||||
|
Untitled Document
|
||||||
|
</message>
|
||||||
|
<message name="IDS_PRINT_SPOOL_FAILED_TITLE_TEXT" desc="Title of a message box when printing fails because of printer issues.">
|
||||||
|
Print Failed
|
||||||
|
</message>
|
||||||
|
<message name="IDS_PRINT_SPOOL_FAILED_ERROR_TEXT" desc="Text in a messagebox when printing fails because of printer issues.">
|
||||||
|
Something went wrong when trying to print. Please check your printer and try again.
|
||||||
|
</message>
|
||||||
|
<message name="IDS_PRINT_PREVIEW_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.
|
||||||
|
</message>
|
||||||
</messages>
|
</messages>
|
||||||
</release>
|
</release>
|
||||||
</grit>
|
</grit>
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
#include <grit/cef_resources.h>
|
||||||
|
#include <grit/cef_strings.h>
|
|
@ -0,0 +1,2 @@
|
||||||
|
#include <grit/cef_resources.h>
|
||||||
|
#include <grit/cef_strings.h>
|
|
@ -0,0 +1 @@
|
||||||
|
<html></html>
|
|
@ -302,6 +302,17 @@ void CEF_CALLBACK browser_host_start_download(struct _cef_browser_host_t* self,
|
||||||
CefString(url));
|
CefString(url));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CEF_CALLBACK browser_host_print(struct _cef_browser_host_t* self) {
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
DCHECK(self);
|
||||||
|
if (!self)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
CefBrowserHostCppToC::Get(self)->Print();
|
||||||
|
}
|
||||||
|
|
||||||
void CEF_CALLBACK browser_host_set_mouse_cursor_change_disabled(
|
void CEF_CALLBACK browser_host_set_mouse_cursor_change_disabled(
|
||||||
struct _cef_browser_host_t* self, int disabled) {
|
struct _cef_browser_host_t* self, int disabled) {
|
||||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
@ -586,6 +597,7 @@ CefBrowserHostCppToC::CefBrowserHostCppToC(CefBrowserHost* cls)
|
||||||
struct_.struct_.set_zoom_level = browser_host_set_zoom_level;
|
struct_.struct_.set_zoom_level = browser_host_set_zoom_level;
|
||||||
struct_.struct_.run_file_dialog = browser_host_run_file_dialog;
|
struct_.struct_.run_file_dialog = browser_host_run_file_dialog;
|
||||||
struct_.struct_.start_download = browser_host_start_download;
|
struct_.struct_.start_download = browser_host_start_download;
|
||||||
|
struct_.struct_.print = browser_host_print;
|
||||||
struct_.struct_.set_mouse_cursor_change_disabled =
|
struct_.struct_.set_mouse_cursor_change_disabled =
|
||||||
browser_host_set_mouse_cursor_change_disabled;
|
browser_host_set_mouse_cursor_change_disabled;
|
||||||
struct_.struct_.is_mouse_cursor_change_disabled =
|
struct_.struct_.is_mouse_cursor_change_disabled =
|
||||||
|
|
|
@ -250,6 +250,16 @@ void CefBrowserHostCToCpp::StartDownload(const CefString& url) {
|
||||||
url.GetStruct());
|
url.GetStruct());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CefBrowserHostCToCpp::Print() {
|
||||||
|
if (CEF_MEMBER_MISSING(struct_, print))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
struct_->print(struct_);
|
||||||
|
}
|
||||||
|
|
||||||
void CefBrowserHostCToCpp::SetMouseCursorChangeDisabled(bool disabled) {
|
void CefBrowserHostCToCpp::SetMouseCursorChangeDisabled(bool disabled) {
|
||||||
if (CEF_MEMBER_MISSING(struct_, set_mouse_cursor_change_disabled))
|
if (CEF_MEMBER_MISSING(struct_, set_mouse_cursor_change_disabled))
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -53,6 +53,7 @@ class CefBrowserHostCToCpp
|
||||||
const std::vector<CefString>& accept_types,
|
const std::vector<CefString>& accept_types,
|
||||||
CefRefPtr<CefRunFileDialogCallback> callback) OVERRIDE;
|
CefRefPtr<CefRunFileDialogCallback> callback) OVERRIDE;
|
||||||
virtual void StartDownload(const CefString& url) OVERRIDE;
|
virtual void StartDownload(const CefString& url) OVERRIDE;
|
||||||
|
virtual void Print() OVERRIDE;
|
||||||
virtual void SetMouseCursorChangeDisabled(bool disabled) OVERRIDE;
|
virtual void SetMouseCursorChangeDisabled(bool disabled) OVERRIDE;
|
||||||
virtual bool IsMouseCursorChangeDisabled() OVERRIDE;
|
virtual bool IsMouseCursorChangeDisabled() OVERRIDE;
|
||||||
virtual bool IsWindowRenderingDisabled() OVERRIDE;
|
virtual bool IsWindowRenderingDisabled() OVERRIDE;
|
||||||
|
|
|
@ -78,6 +78,7 @@ BEGIN
|
||||||
MENUITEM "Zoom Reset", ID_TESTS_ZOOM_RESET
|
MENUITEM "Zoom Reset", ID_TESTS_ZOOM_RESET
|
||||||
MENUITEM "Begin Tracing", ID_TESTS_TRACING_BEGIN
|
MENUITEM "Begin Tracing", ID_TESTS_TRACING_BEGIN
|
||||||
MENUITEM "End Tracing", ID_TESTS_TRACING_END
|
MENUITEM "End Tracing", ID_TESTS_TRACING_END
|
||||||
|
MENUITEM "Print", ID_TESTS_PRINT
|
||||||
MENUITEM "Other Tests", ID_TESTS_OTHER_TESTS
|
MENUITEM "Other Tests", ID_TESTS_OTHER_TESTS
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
|
@ -149,6 +149,14 @@ gboolean EndTracingActivated(GtkWidget* widget) {
|
||||||
return FALSE; // Don't stop this message.
|
return FALSE; // Don't stop this message.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Callback for Tests > Print menu item.
|
||||||
|
gboolean PrintActivated(GtkWidget* widget) {
|
||||||
|
if (g_handler.get())
|
||||||
|
g_handler->GetBrowser()->GetHost()->Print();
|
||||||
|
|
||||||
|
return FALSE; // Don't stop this message.
|
||||||
|
}
|
||||||
|
|
||||||
// Callback for Tests > Other Tests... menu item.
|
// Callback for Tests > Other Tests... menu item.
|
||||||
gboolean OtherTestsActivated(GtkWidget* widget) {
|
gboolean OtherTestsActivated(GtkWidget* widget) {
|
||||||
if (g_handler.get() && g_handler->GetBrowserId())
|
if (g_handler.get() && g_handler->GetBrowserId())
|
||||||
|
@ -232,6 +240,8 @@ GtkWidget* CreateMenuBar() {
|
||||||
G_CALLBACK(BeginTracingActivated));
|
G_CALLBACK(BeginTracingActivated));
|
||||||
AddMenuEntry(debug_menu, "End Tracing",
|
AddMenuEntry(debug_menu, "End Tracing",
|
||||||
G_CALLBACK(EndTracingActivated));
|
G_CALLBACK(EndTracingActivated));
|
||||||
|
AddMenuEntry(debug_menu, "Print",
|
||||||
|
G_CALLBACK(PrintActivated));
|
||||||
AddMenuEntry(debug_menu, "Other Tests",
|
AddMenuEntry(debug_menu, "Other Tests",
|
||||||
G_CALLBACK(OtherTestsActivated));
|
G_CALLBACK(OtherTestsActivated));
|
||||||
return menu_bar;
|
return menu_bar;
|
||||||
|
|
|
@ -217,6 +217,7 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
|
||||||
- (IBAction)testZoomReset:(id)sender;
|
- (IBAction)testZoomReset:(id)sender;
|
||||||
- (IBAction)testBeginTracing:(id)sender;
|
- (IBAction)testBeginTracing:(id)sender;
|
||||||
- (IBAction)testEndTracing:(id)sender;
|
- (IBAction)testEndTracing:(id)sender;
|
||||||
|
- (IBAction)testPrint:(id)sender;
|
||||||
- (IBAction)testOtherTests:(id)sender;
|
- (IBAction)testOtherTests:(id)sender;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -266,6 +267,9 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
|
||||||
[testMenu addItemWithTitle:@"End Tracing"
|
[testMenu addItemWithTitle:@"End Tracing"
|
||||||
action:@selector(testEndTracing:)
|
action:@selector(testEndTracing:)
|
||||||
keyEquivalent:@""];
|
keyEquivalent:@""];
|
||||||
|
[testMenu addItemWithTitle:@"Print"
|
||||||
|
action:@selector(testPrint:)
|
||||||
|
keyEquivalent:@""];
|
||||||
[testMenu addItemWithTitle:@"Other Tests"
|
[testMenu addItemWithTitle:@"Other Tests"
|
||||||
action:@selector(testOtherTests:)
|
action:@selector(testOtherTests:)
|
||||||
keyEquivalent:@""];
|
keyEquivalent:@""];
|
||||||
|
@ -428,6 +432,11 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
|
||||||
g_handler->EndTracing();
|
g_handler->EndTracing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (IBAction)testPrint:(id)sender {
|
||||||
|
if (g_handler.get() && g_handler->GetBrowserId())
|
||||||
|
g_handler->GetBrowser()->GetHost()->Print();
|
||||||
|
}
|
||||||
|
|
||||||
- (IBAction)testOtherTests:(id)sender {
|
- (IBAction)testOtherTests:(id)sender {
|
||||||
if (g_handler.get() && g_handler->GetBrowserId())
|
if (g_handler.get() && g_handler->GetBrowserId())
|
||||||
RunOtherTests(g_handler->GetBrowser());
|
RunOtherTests(g_handler->GetBrowser());
|
||||||
|
|
|
@ -430,6 +430,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
|
||||||
case ID_TESTS_TRACING_END:
|
case ID_TESTS_TRACING_END:
|
||||||
g_handler->EndTracing();
|
g_handler->EndTracing();
|
||||||
return 0;
|
return 0;
|
||||||
|
case ID_TESTS_PRINT:
|
||||||
|
if(browser.get())
|
||||||
|
browser->GetHost()->Print();
|
||||||
|
return 0;
|
||||||
case ID_TESTS_OTHER_TESTS:
|
case ID_TESTS_OTHER_TESTS:
|
||||||
if (browser.get())
|
if (browser.get())
|
||||||
RunOtherTests(browser);
|
RunOtherTests(browser);
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
<li><a href="http://webglsamples.googlecode.com/hg/field/field.html">WebGL</a></li>
|
<li><a href="http://webglsamples.googlecode.com/hg/field/field.html">WebGL</a></li>
|
||||||
<li><a href="http://apprtc.appspot.com/">WebRTC</a> - requires "enable-media-stream" flag</li>
|
<li><a href="http://apprtc.appspot.com/">WebRTC</a> - requires "enable-media-stream" flag</li>
|
||||||
<li><a href="http://tests/xmlhttprequest">XMLHttpRequest</a></li>
|
<li><a href="http://tests/xmlhttprequest">XMLHttpRequest</a></li>
|
||||||
|
<li><a href="javascript:window.print();">Print this page with "javascript:window.print();"</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -31,12 +31,13 @@
|
||||||
#define ID_TESTS_OTHER_TESTS 32702
|
#define ID_TESTS_OTHER_TESTS 32702
|
||||||
#define ID_TESTS_PLUGIN_INFO 32703
|
#define ID_TESTS_PLUGIN_INFO 32703
|
||||||
#define ID_TESTS_POPUP 32704
|
#define ID_TESTS_POPUP 32704
|
||||||
#define ID_TESTS_REQUEST 32705
|
#define ID_TESTS_PRINT 32705
|
||||||
#define ID_TESTS_TRACING_BEGIN 32706
|
#define ID_TESTS_REQUEST 32706
|
||||||
#define ID_TESTS_TRACING_END 32707
|
#define ID_TESTS_TRACING_BEGIN 32707
|
||||||
#define ID_TESTS_ZOOM_IN 32708
|
#define ID_TESTS_TRACING_END 32708
|
||||||
#define ID_TESTS_ZOOM_OUT 32709
|
#define ID_TESTS_ZOOM_IN 32709
|
||||||
#define ID_TESTS_ZOOM_RESET 32710
|
#define ID_TESTS_ZOOM_OUT 32710
|
||||||
|
#define ID_TESTS_ZOOM_RESET 32711
|
||||||
#define IDC_STATIC -1
|
#define IDC_STATIC -1
|
||||||
#define IDS_BINDING 1000
|
#define IDS_BINDING 1000
|
||||||
#define IDS_DIALOGS 1001
|
#define IDS_DIALOGS 1001
|
||||||
|
|
|
@ -368,7 +368,7 @@
|
||||||
# gtk requires gmodule, but it does not list it as a dependency
|
# gtk requires gmodule, but it does not list it as a dependency
|
||||||
# in some misconfigured systems.
|
# in some misconfigured systems.
|
||||||
# gtkglext is required by the cefclient OSR example.
|
# gtkglext is required by the cefclient OSR example.
|
||||||
'gtk_packages': 'gmodule-2.0 gtk+-2.0 gthread-2.0 gtkglext-1.0',
|
'gtk_packages': 'gmodule-2.0 gtk+-2.0 gthread-2.0 gtkglext-1.0 gtk+-unix-print-2.0',
|
||||||
},
|
},
|
||||||
'direct_dependent_settings': {
|
'direct_dependent_settings': {
|
||||||
'cflags': [
|
'cflags': [
|
||||||
|
|
Loading…
Reference in New Issue