diff options
author | dgn <dgn@chromium.org> | 2015-02-03 02:38:44 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-02-03 10:39:36 +0000 |
commit | 2fa98a5958ad5ecb86484acbeed3a05326647d4a (patch) | |
tree | 7aa7146cd6d895f6eb3d8d677f14cef995ec16fe | |
parent | 1069b7c12046e5e4bd6b607b4543db3c5cfab036 (diff) | |
download | chromium_src-2fa98a5958ad5ecb86484acbeed3a05326647d4a.zip chromium_src-2fa98a5958ad5ecb86484acbeed3a05326647d4a.tar.gz chromium_src-2fa98a5958ad5ecb86484acbeed3a05326647d4a.tar.bz2 |
Refactor webview to use //components/printing
Some printing related //android_webview were copied over from
//chrome. Now that the ones in //chrome can move to a component,
webview should also use these files.
Depends on https://codereview.chromium.org/811563008/
BUG=444883, 311308
Review URL: https://codereview.chromium.org/822133003
Cr-Commit-Position: refs/heads/master@{#314307}
20 files changed, 112 insertions, 3261 deletions
diff --git a/android_webview/android_webview.gyp b/android_webview/android_webview.gyp index 4018c9f..aad1cc7 100644 --- a/android_webview/android_webview.gyp +++ b/android_webview/android_webview.gyp @@ -103,6 +103,8 @@ '../components/components.gyp:cdm_renderer', '../components/components.gyp:data_reduction_proxy_core_browser', '../components/components.gyp:navigation_interception', + '../components/components.gyp:printing_common', + '../components/components.gyp:printing_renderer', '../components/components.gyp:visitedlink_browser', '../components/components.gyp:visitedlink_renderer', '../components/components.gyp:web_contents_delegate_android', @@ -235,8 +237,6 @@ 'common/aw_switches.cc', 'common/aw_switches.h', 'common/devtools_instrumentation.h', - 'common/print_messages.cc', - 'common/print_messages.h', 'common/render_view_messages.cc', 'common/render_view_messages.h', 'common/url_constants.cc', @@ -254,16 +254,14 @@ 'renderer/aw_message_port_client.h', 'renderer/aw_permission_client.cc', 'renderer/aw_permission_client.h', + 'renderer/aw_print_web_view_helper_delegate.cc', + 'renderer/aw_print_web_view_helper_delegate.h', 'renderer/aw_render_process_observer.cc', 'renderer/aw_render_process_observer.h', 'renderer/aw_render_frame_ext.cc', 'renderer/aw_render_frame_ext.h', 'renderer/aw_render_view_ext.cc', 'renderer/aw_render_view_ext.h', - 'renderer/print_web_view_helper.cc', - 'renderer/print_web_view_helper.h', - 'renderer/print_web_view_helper_android.cc', - 'renderer/print_web_view_helper_linux.cc', 'renderer/print_render_frame_observer.cc', 'renderer/print_render_frame_observer.h', ], diff --git a/android_webview/browser/DEPS b/android_webview/browser/DEPS index ed69d9f..217bfa7 100644 --- a/android_webview/browser/DEPS +++ b/android_webview/browser/DEPS @@ -16,6 +16,7 @@ include_rules = [ "+components/cdm/browser", "+components/data_reduction_proxy/core/browser", "+components/navigation_interception", + "+components/printing/common", "+components/user_prefs", "+components/visitedlink/browser", "+components/webdata/common", diff --git a/android_webview/browser/aw_printing_message_filter.cc b/android_webview/browser/aw_printing_message_filter.cc index 524aed8..f0fdee9 100644 --- a/android_webview/browser/aw_printing_message_filter.cc +++ b/android_webview/browser/aw_printing_message_filter.cc @@ -5,7 +5,7 @@ #include "android_webview/browser/aw_printing_message_filter.h" #include "android_webview/browser/renderer_host/print_manager.h" -#include "android_webview/common/print_messages.h" +#include "components/printing/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" diff --git a/android_webview/browser/renderer_host/print_manager.cc b/android_webview/browser/renderer_host/print_manager.cc index 14c2ace..ba29619 100644 --- a/android_webview/browser/renderer_host/print_manager.cc +++ b/android_webview/browser/renderer_host/print_manager.cc @@ -5,12 +5,12 @@ #include "android_webview/browser/renderer_host/print_manager.h" #include "android_webview/browser/aw_browser_context.h" -#include "android_webview/common/print_messages.h" #include "android_webview/common/render_view_messages.h" #include "base/android/scoped_java_ref.h" #include "base/callback.h" #include "base/files/file_util.h" #include "base/logging.h" +#include "components/printing/common/print_messages.h" #include "content/public/browser/browser_thread.h" #include "printing/print_settings.h" diff --git a/android_webview/common/DEPS b/android_webview/common/DEPS index 49c3ea0..3f08e03 100644 --- a/android_webview/common/DEPS +++ b/android_webview/common/DEPS @@ -1,13 +1,5 @@ include_rules = [ "-android_webview", "+android_webview/common", - -# TODO(sgurun) remove these deps after crbug.com/322276 is resolved - "+printing", - "+third_party/WebKit/public/web/WebPrintScalingOption.h", - "+ui/gfx/native_widget_types.h", - "+ui/gfx/rect.h", - "+ui/gfx/size.h", - - "+ui/gl/gpu_memory_buffer.h", + "+components/printing/common", ] diff --git a/android_webview/common/android_webview_message_generator.h b/android_webview/common/android_webview_message_generator.h index f5dcce8..de4eb1b 100644 --- a/android_webview/common/android_webview_message_generator.h +++ b/android_webview/common/android_webview_message_generator.h @@ -5,5 +5,4 @@ // Multiply-included file, hence no include guard. #include "android_webview/common/aw_message_port_messages.h" -#include "android_webview/common/print_messages.h" #include "android_webview/common/render_view_messages.h" diff --git a/android_webview/common/print_messages.cc b/android_webview/common/print_messages.cc deleted file mode 100644 index 87e33b8..0000000 --- a/android_webview/common/print_messages.cc +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// TODO(sgurun) copied from chrome/common. Remove after crbug.com/322276 - -#include "android_webview/common/print_messages.h" - -#include "base/basictypes.h" -#include "base/strings/string16.h" -#include "ui/gfx/geometry/size.h" - -PrintMsg_Print_Params::PrintMsg_Print_Params() - : page_size(), - content_size(), - printable_area(), - margin_top(0), - margin_left(0), - dpi(0), - min_shrink(0), - max_shrink(0), - desired_dpi(0), - document_cookie(0), - selection_only(false), - supports_alpha_blend(false), - preview_ui_id(-1), - preview_request_id(0), - is_first_request(false), - print_scaling_option(blink::WebPrintScalingOptionSourceSize), - print_to_pdf(false), - display_header_footer(false), - title(), - url(), - should_print_backgrounds(false) { -} - -PrintMsg_Print_Params::~PrintMsg_Print_Params() {} - -void PrintMsg_Print_Params::Reset() { - page_size = gfx::Size(); - content_size = gfx::Size(); - printable_area = gfx::Rect(); - margin_top = 0; - margin_left = 0; - dpi = 0; - min_shrink = 0; - max_shrink = 0; - desired_dpi = 0; - document_cookie = 0; - selection_only = false; - supports_alpha_blend = false; - preview_ui_id = -1; - preview_request_id = 0; - is_first_request = false; - print_scaling_option = blink::WebPrintScalingOptionSourceSize; - print_to_pdf = false; - display_header_footer = false; - title = base::string16(); - url = base::string16(); - should_print_backgrounds = false; -} - -PrintMsg_PrintPages_Params::PrintMsg_PrintPages_Params() - : pages() { -} - -PrintMsg_PrintPages_Params::~PrintMsg_PrintPages_Params() {} - -void PrintMsg_PrintPages_Params::Reset() { - params.Reset(); - pages = std::vector<int>(); -} - -PrintHostMsg_RequestPrintPreview_Params:: - PrintHostMsg_RequestPrintPreview_Params() - : is_modifiable(false), - webnode_only(false), - has_selection(false), - selection_only(false) { -} - -PrintHostMsg_RequestPrintPreview_Params:: - ~PrintHostMsg_RequestPrintPreview_Params() {} diff --git a/android_webview/common/print_messages.h b/android_webview/common/print_messages.h deleted file mode 100644 index 294241b..0000000 --- a/android_webview/common/print_messages.h +++ /dev/null @@ -1,450 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// IPC messages for printing. -// Multiply-included message file, hence no include guard. - -// TODO(sgurun) copied from chrome/common. Remove after crbug.com/322276 - -#include <string> -#include <vector> - -#include "base/memory/shared_memory.h" -#include "base/values.h" -#include "ipc/ipc_message_macros.h" -#include "printing/page_size_margins.h" -#include "printing/print_job_constants.h" -#include "third_party/WebKit/public/web/WebPrintScalingOption.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/gfx/ipc/gfx_param_traits.h" -#include "ui/gfx/native_widget_types.h" - -#ifndef AW_COMMON_PRINT_MESSAGES_H_ -#define AW_COMMON_PRINT_MESSAGES_H_ - -struct PrintMsg_Print_Params { - PrintMsg_Print_Params(); - ~PrintMsg_Print_Params(); - - // Resets the members of the struct to 0. - void Reset(); - - gfx::Size page_size; - gfx::Size content_size; - gfx::Rect printable_area; - int margin_top; - int margin_left; - double dpi; - double min_shrink; - double max_shrink; - int desired_dpi; - int document_cookie; - bool selection_only; - bool supports_alpha_blend; - int32 preview_ui_id; - int preview_request_id; - bool is_first_request; - blink::WebPrintScalingOption print_scaling_option; - bool print_to_pdf; - bool display_header_footer; - base::string16 title; - base::string16 url; - bool should_print_backgrounds; -}; - -struct PrintMsg_PrintPages_Params { - PrintMsg_PrintPages_Params(); - ~PrintMsg_PrintPages_Params(); - - // Resets the members of the struct to 0. - void Reset(); - - PrintMsg_Print_Params params; - std::vector<int> pages; -}; - -struct PrintHostMsg_RequestPrintPreview_Params { - PrintHostMsg_RequestPrintPreview_Params(); - ~PrintHostMsg_RequestPrintPreview_Params(); - bool is_modifiable; - bool webnode_only; - bool has_selection; - bool selection_only; -}; - -#endif // AW_COMMON_PRINT_MESSAGES_H_ - -#define IPC_MESSAGE_START PrintMsgStart - -IPC_ENUM_TRAITS_MAX_VALUE(printing::MarginType, - printing::MarginType::MARGIN_TYPE_LAST) - -IPC_ENUM_TRAITS_MAX_VALUE( - blink::WebPrintScalingOption, - blink::WebPrintScalingOption::WebPrintScalingOptionLast) - -// Parameters for a render request. -IPC_STRUCT_TRAITS_BEGIN(PrintMsg_Print_Params) - // Physical size of the page, including non-printable margins, - // in pixels according to dpi. - IPC_STRUCT_TRAITS_MEMBER(page_size) - - // In pixels according to dpi_x and dpi_y. - IPC_STRUCT_TRAITS_MEMBER(content_size) - - // Physical printable area of the page in pixels according to dpi. - IPC_STRUCT_TRAITS_MEMBER(printable_area) - - // The y-offset of the printable area, in pixels according to dpi. - IPC_STRUCT_TRAITS_MEMBER(margin_top) - - // The x-offset of the printable area, in pixels according to dpi. - IPC_STRUCT_TRAITS_MEMBER(margin_left) - - // Specifies dots per inch. - IPC_STRUCT_TRAITS_MEMBER(dpi) - - // Minimum shrink factor. See PrintSettings::min_shrink for more information. - IPC_STRUCT_TRAITS_MEMBER(min_shrink) - - // Maximum shrink factor. See PrintSettings::max_shrink for more information. - IPC_STRUCT_TRAITS_MEMBER(max_shrink) - - // Desired apparent dpi on paper. - IPC_STRUCT_TRAITS_MEMBER(desired_dpi) - - // Cookie for the document to ensure correctness. - IPC_STRUCT_TRAITS_MEMBER(document_cookie) - - // Should only print currently selected text. - IPC_STRUCT_TRAITS_MEMBER(selection_only) - - // Does the printer support alpha blending? - IPC_STRUCT_TRAITS_MEMBER(supports_alpha_blend) - - // *** Parameters below are used only for print preview. *** - - // The print preview ui associated with this request. - IPC_STRUCT_TRAITS_MEMBER(preview_ui_id) - - // The id of the preview request. - IPC_STRUCT_TRAITS_MEMBER(preview_request_id) - - // True if this is the first preview request. - IPC_STRUCT_TRAITS_MEMBER(is_first_request) - - // Specifies the page scaling option for preview printing. - IPC_STRUCT_TRAITS_MEMBER(print_scaling_option) - - // True if print to pdf is requested. - IPC_STRUCT_TRAITS_MEMBER(print_to_pdf) - - // Specifies if the header and footer should be rendered. - IPC_STRUCT_TRAITS_MEMBER(display_header_footer) - - // Title string to be printed as header if requested by the user. - IPC_STRUCT_TRAITS_MEMBER(title) - - // URL string to be printed as footer if requested by the user. - IPC_STRUCT_TRAITS_MEMBER(url) - - // True if print backgrounds is requested by the user. - IPC_STRUCT_TRAITS_MEMBER(should_print_backgrounds) -IPC_STRUCT_TRAITS_END() - -IPC_STRUCT_BEGIN(PrintMsg_PrintPage_Params) - // Parameters to render the page as a printed page. It must always be the same - // value for all the document. - IPC_STRUCT_MEMBER(PrintMsg_Print_Params, params) - - // The page number is the indicator of the square that should be rendered - // according to the layout specified in PrintMsg_Print_Params. - IPC_STRUCT_MEMBER(int, page_number) -IPC_STRUCT_END() - -IPC_STRUCT_TRAITS_BEGIN(PrintHostMsg_RequestPrintPreview_Params) - IPC_STRUCT_TRAITS_MEMBER(is_modifiable) - IPC_STRUCT_TRAITS_MEMBER(webnode_only) - IPC_STRUCT_TRAITS_MEMBER(has_selection) - IPC_STRUCT_TRAITS_MEMBER(selection_only) -IPC_STRUCT_TRAITS_END() - -IPC_STRUCT_TRAITS_BEGIN(printing::PageSizeMargins) - IPC_STRUCT_TRAITS_MEMBER(content_width) - IPC_STRUCT_TRAITS_MEMBER(content_height) - IPC_STRUCT_TRAITS_MEMBER(margin_left) - IPC_STRUCT_TRAITS_MEMBER(margin_right) - IPC_STRUCT_TRAITS_MEMBER(margin_top) - IPC_STRUCT_TRAITS_MEMBER(margin_bottom) -IPC_STRUCT_TRAITS_END() - -IPC_STRUCT_TRAITS_BEGIN(PrintMsg_PrintPages_Params) - // Parameters to render the page as a printed page. It must always be the same - // value for all the document. - IPC_STRUCT_TRAITS_MEMBER(params) - - // If empty, this means a request to render all the printed pages. - IPC_STRUCT_TRAITS_MEMBER(pages) -IPC_STRUCT_TRAITS_END() - -// Parameters to describe a rendered document. -IPC_STRUCT_BEGIN(PrintHostMsg_DidPreviewDocument_Params) - // True when we can reuse existing preview data. |metafile_data_handle| and - // |data_size| should not be used when this is true. - IPC_STRUCT_MEMBER(bool, reuse_existing_data) - - // A shared memory handle to metafile data. - IPC_STRUCT_MEMBER(base::SharedMemoryHandle, metafile_data_handle) - - // Size of metafile data. - IPC_STRUCT_MEMBER(uint32, data_size) - - // Cookie for the document to ensure correctness. - IPC_STRUCT_MEMBER(int, document_cookie) - - // Store the expected pages count. - IPC_STRUCT_MEMBER(int, expected_pages_count) - - // Whether the preview can be modified. - IPC_STRUCT_MEMBER(bool, modifiable) - - // The id of the preview request. - IPC_STRUCT_MEMBER(int, preview_request_id) -IPC_STRUCT_END() - -// Parameters to describe a rendered preview page. -IPC_STRUCT_BEGIN(PrintHostMsg_DidPreviewPage_Params) - // A shared memory handle to metafile data for a draft document of the page. - IPC_STRUCT_MEMBER(base::SharedMemoryHandle, metafile_data_handle) - - // Size of metafile data. - IPC_STRUCT_MEMBER(uint32, data_size) - - // |page_number| is zero-based and can be |printing::INVALID_PAGE_INDEX| if it - // is just a check. - IPC_STRUCT_MEMBER(int, page_number) - - // The id of the preview request. - IPC_STRUCT_MEMBER(int, preview_request_id) -IPC_STRUCT_END() - -// Parameters sent along with the page count. -IPC_STRUCT_BEGIN(PrintHostMsg_DidGetPreviewPageCount_Params) - // Cookie for the document to ensure correctness. - IPC_STRUCT_MEMBER(int, document_cookie) - - // Total page count. - IPC_STRUCT_MEMBER(int, page_count) - - // Indicates whether the previewed document is modifiable. - IPC_STRUCT_MEMBER(bool, is_modifiable) - - // The id of the preview request. - IPC_STRUCT_MEMBER(int, preview_request_id) - - // Indicates whether the existing preview data needs to be cleared or not. - IPC_STRUCT_MEMBER(bool, clear_preview_data) -IPC_STRUCT_END() - -// Parameters to describe a rendered page. -IPC_STRUCT_BEGIN(PrintHostMsg_DidPrintPage_Params) - // A shared memory handle to the EMF data. This data can be quite large so a - // memory map needs to be used. - IPC_STRUCT_MEMBER(base::SharedMemoryHandle, metafile_data_handle) - - // Size of the metafile data. - IPC_STRUCT_MEMBER(uint32, data_size) - - // Cookie for the document to ensure correctness. - IPC_STRUCT_MEMBER(int, document_cookie) - - // Page number. - IPC_STRUCT_MEMBER(int, page_number) - - // Shrink factor used to render this page. - IPC_STRUCT_MEMBER(double, actual_shrink) - - // The size of the page the page author specified. - IPC_STRUCT_MEMBER(gfx::Size, page_size) - - // The printable area the page author specified. - IPC_STRUCT_MEMBER(gfx::Rect, content_area) -IPC_STRUCT_END() - -// Parameters for the IPC message ViewHostMsg_ScriptedPrint -IPC_STRUCT_BEGIN(PrintHostMsg_ScriptedPrint_Params) - IPC_STRUCT_MEMBER(int, cookie) - IPC_STRUCT_MEMBER(int, expected_pages_count) - IPC_STRUCT_MEMBER(bool, has_selection) - IPC_STRUCT_MEMBER(printing::MarginType, margin_type) -IPC_STRUCT_END() - - -// Messages sent from the browser to the renderer. - -// Tells the render view to initiate print preview for the entire document. -IPC_MESSAGE_ROUTED1(PrintMsg_InitiatePrintPreview, bool /* selection_only */) - -// Tells the render frame to initiate printing or print preview for a particular -// node, depending on which mode the render frame is in. -IPC_MESSAGE_ROUTED0(PrintMsg_PrintNodeUnderContextMenu) - -// Tells the renderer to print the print preview tab's PDF plugin without -// showing the print dialog. (This is the final step in the print preview -// workflow.) -IPC_MESSAGE_ROUTED1(PrintMsg_PrintForPrintPreview, - base::DictionaryValue /* settings */) - -// Tells the render view to switch the CSS to print media type, renders every -// requested pages and switch back the CSS to display media type. -IPC_MESSAGE_ROUTED0(PrintMsg_PrintPages) - -// Tells the render view that printing is done so it can clean up. -IPC_MESSAGE_ROUTED1(PrintMsg_PrintingDone, - bool /* success */) - -// Tells the render view whether scripted printing is blocked or not. -IPC_MESSAGE_ROUTED1(PrintMsg_SetScriptedPrintingBlocked, - bool /* blocked */) - -// Tells the render view to switch the CSS to print media type, renders every -// requested pages for print preview using the given |settings|. This gets -// called multiple times as the user updates settings. -IPC_MESSAGE_ROUTED1(PrintMsg_PrintPreview, - base::DictionaryValue /* settings */) - -// Like PrintMsg_PrintPages, but using the print preview document's frame/node. -IPC_MESSAGE_ROUTED0(PrintMsg_PrintForSystemDialog) - -// Tells a renderer to stop blocking script initiated printing. -IPC_MESSAGE_ROUTED0(PrintMsg_ResetScriptedPrintCount) - -// Messages sent from the renderer to the browser. - -#if defined(OS_WIN) -// Duplicates a shared memory handle from the renderer to the browser. Then -// the renderer can flush the handle. -IPC_SYNC_MESSAGE_ROUTED1_1(PrintHostMsg_DuplicateSection, - base::SharedMemoryHandle /* renderer handle */, - base::SharedMemoryHandle /* browser handle */) -#endif - -// Check if printing is enabled. -IPC_SYNC_MESSAGE_ROUTED0_1(PrintHostMsg_IsPrintingEnabled, - bool /* is_enabled */) - -// Tells the browser that the renderer is done calculating the number of -// rendered pages according to the specified settings. -IPC_MESSAGE_ROUTED2(PrintHostMsg_DidGetPrintedPagesCount, - int /* rendered document cookie */, - int /* number of rendered pages */) - -// Sends the document cookie of the current printer query to the browser. -IPC_MESSAGE_ROUTED1(PrintHostMsg_DidGetDocumentCookie, - int /* rendered document cookie */) - -// Tells the browser that the print dialog has been shown. -IPC_MESSAGE_ROUTED0(PrintHostMsg_DidShowPrintDialog) - -// Sends back to the browser the rendered "printed page" that was requested by -// a ViewMsg_PrintPage message or from scripted printing. The memory handle in -// this message is already valid in the browser process. -IPC_MESSAGE_ROUTED1(PrintHostMsg_DidPrintPage, - PrintHostMsg_DidPrintPage_Params /* page content */) - -// The renderer wants to know the default print settings. -IPC_SYNC_MESSAGE_ROUTED0_1(PrintHostMsg_GetDefaultPrintSettings, - PrintMsg_Print_Params /* default_settings */) - -// The renderer wants to update the current print settings with new -// |job_settings|. -IPC_SYNC_MESSAGE_ROUTED2_1(PrintHostMsg_UpdatePrintSettings, - int /* document_cookie */, - base::DictionaryValue /* job_settings */, - PrintMsg_PrintPages_Params /* current_settings */) - -// It's the renderer that controls the printing process when it is generated -// by javascript. This step is about showing UI to the user to select the -// final print settings. The output parameter is the same as -// ViewMsg_PrintPages which is executed implicitly. -IPC_SYNC_MESSAGE_ROUTED1_1(PrintHostMsg_ScriptedPrint, - PrintHostMsg_ScriptedPrint_Params, - PrintMsg_PrintPages_Params - /* settings chosen by the user*/) - -#if defined(OS_ANDROID) -// Asks the browser to create a temporary file for the renderer to fill -// in resulting PdfMetafileSkia in printing. -IPC_SYNC_MESSAGE_CONTROL1_2(PrintHostMsg_AllocateTempFileForPrinting, - int /* render_view_id */, - base::FileDescriptor /* temp file fd */, - int /* fd in browser*/) -IPC_MESSAGE_CONTROL2(PrintHostMsg_TempFileForPrintingWritten, - int /* render_view_id */, - int /* fd in browser */) -#endif -// Asks the browser to do print preview. -IPC_MESSAGE_ROUTED1(PrintHostMsg_RequestPrintPreview, - PrintHostMsg_RequestPrintPreview_Params /* params */) - -// Notify the browser the number of pages in the print preview document. -IPC_MESSAGE_ROUTED1(PrintHostMsg_DidGetPreviewPageCount, - PrintHostMsg_DidGetPreviewPageCount_Params /* params */) - -// Notify the browser of the default page layout according to the currently -// selected printer and page size. -// |printable_area_in_points| Specifies the printable area in points. -// |has_custom_page_size_style| is true when the printing frame has a custom -// page size css otherwise false. -IPC_MESSAGE_ROUTED3(PrintHostMsg_DidGetDefaultPageLayout, - printing::PageSizeMargins /* page layout in points */, - gfx::Rect /* printable area in points */, - bool /* has custom page size style */) - -// Notify the browser a print preview page has been rendered. -IPC_MESSAGE_ROUTED1(PrintHostMsg_DidPreviewPage, - PrintHostMsg_DidPreviewPage_Params /* params */) - -// Asks the browser whether the print preview has been cancelled. -IPC_SYNC_MESSAGE_ROUTED2_1(PrintHostMsg_CheckForCancel, - int32 /* PrintPreviewUI ID */, - int /* request id */, - bool /* print preview cancelled */) - -// Sends back to the browser the complete rendered document (non-draft mode, -// used for printing) that was requested by a PrintMsg_PrintPreview message. -// The memory handle in this message is already valid in the browser process. -IPC_MESSAGE_ROUTED1(PrintHostMsg_MetafileReadyForPrinting, - PrintHostMsg_DidPreviewDocument_Params /* params */) - -// Tell the browser printing failed. -IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintingFailed, - int /* document cookie */) - -// Tell the browser print preview failed. -IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintPreviewFailed, - int /* document cookie */) - -// Tell the browser print preview was cancelled. -IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintPreviewCancelled, - int /* document cookie */) - -// Tell the browser print preview found the selected printer has invalid -// settings (which typically caused by disconnected network printer or printer -// driver is bogus). -IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintPreviewInvalidPrinterSettings, - int /* document cookie */) - -// Run a nested message loop in the renderer until print preview for -// window.print() finishes. -IPC_SYNC_MESSAGE_ROUTED0_0(PrintHostMsg_SetupScriptedPrintPreview) - -// Tell the browser to show the print preview, when the document is sufficiently -// loaded such that the renderer can determine whether it is modifiable or not. -IPC_MESSAGE_ROUTED1(PrintHostMsg_ShowScriptedPrintPreview, - bool /* is_modifiable */) - -// Notify the browser that the PDF in the initiator renderer has disabled print -// scaling option. -IPC_MESSAGE_ROUTED0(PrintHostMsg_PrintPreviewScalingDisabled) diff --git a/android_webview/renderer/DEPS b/android_webview/renderer/DEPS index 6c1ad13..7f387ce 100644 --- a/android_webview/renderer/DEPS +++ b/android_webview/renderer/DEPS @@ -5,6 +5,8 @@ include_rules = [ "+components/autofill/content/renderer", "+components/cdm/renderer", + "+components/printing/common", + "+components/printing/renderer", "+components/visitedlink/renderer", "+content/public/renderer", diff --git a/android_webview/renderer/aw_content_renderer_client.cc b/android_webview/renderer/aw_content_renderer_client.cc index 3771059..c12cc7f 100644 --- a/android_webview/renderer/aw_content_renderer_client.cc +++ b/android_webview/renderer/aw_content_renderer_client.cc @@ -10,14 +10,15 @@ #include "android_webview/renderer/aw_key_systems.h" #include "android_webview/renderer/aw_message_port_client.h" #include "android_webview/renderer/aw_permission_client.h" +#include "android_webview/renderer/aw_print_web_view_helper_delegate.h" #include "android_webview/renderer/aw_render_frame_ext.h" #include "android_webview/renderer/aw_render_view_ext.h" #include "android_webview/renderer/print_render_frame_observer.h" -#include "android_webview/renderer/print_web_view_helper.h" #include "base/message_loop/message_loop.h" #include "base/strings/utf_string_conversions.h" #include "components/autofill/content/renderer/autofill_agent.h" #include "components/autofill/content/renderer/password_autofill_agent.h" +#include "components/printing/renderer/print_web_view_helper.h" #include "components/visitedlink/renderer/visitedlink_slave.h" #include "content/public/common/url_constants.h" #include "content/public/renderer/document_state.h" @@ -147,7 +148,10 @@ void AwContentRendererClient::RenderViewCreated( content::RenderView* render_view) { AwRenderViewExt::RenderViewCreated(render_view); - new printing::PrintWebViewHelper(render_view); + new printing::PrintWebViewHelper( + render_view, + scoped_ptr<printing::PrintWebViewHelper::Delegate>( + new AwPrintWebViewHelperDelegate())); } bool AwContentRendererClient::HasErrorPage(int http_status_code, diff --git a/android_webview/renderer/aw_print_web_view_helper_delegate.cc b/android_webview/renderer/aw_print_web_view_helper_delegate.cc new file mode 100644 index 0000000..242cfdb --- /dev/null +++ b/android_webview/renderer/aw_print_web_view_helper_delegate.cc @@ -0,0 +1,44 @@ +// Copyright 2015 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 "android_webview/renderer/aw_print_web_view_helper_delegate.h" + +#include "third_party/WebKit/public/web/WebElement.h" + +namespace android_webview { + +AwPrintWebViewHelperDelegate::~AwPrintWebViewHelperDelegate(){ +} + +bool AwPrintWebViewHelperDelegate::CancelPrerender( + content::RenderView* render_view, int routing_id) { + return false; +} + +blink::WebElement AwPrintWebViewHelperDelegate::GetPdfElement( + blink::WebLocalFrame* frame) { + return blink::WebElement(); +} + +bool AwPrintWebViewHelperDelegate::IsOutOfProcessPdfEnabled() { + return false; +} + +bool AwPrintWebViewHelperDelegate::IsPrintPreviewEnabled() { + return false; +} + +bool AwPrintWebViewHelperDelegate::IsAskPrintSettingsEnabled() { + return false; +} + +bool AwPrintWebViewHelperDelegate::IsScriptedPrintEnabled() { + return false; +} + +bool AwPrintWebViewHelperDelegate::OverridePrint(blink::WebLocalFrame* frame) { + return false; +} + +} // namespace android_webview diff --git a/android_webview/renderer/aw_print_web_view_helper_delegate.h b/android_webview/renderer/aw_print_web_view_helper_delegate.h new file mode 100644 index 0000000..e5a893c --- /dev/null +++ b/android_webview/renderer/aw_print_web_view_helper_delegate.h @@ -0,0 +1,28 @@ +// Copyright 2015 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 ANDROID_WEBVIEW_RENDERER_AW_PRINT_WEB_VIEW_HELPER_DELEGATE_H_ +#define ANDROID_WEBVIEW_RENDERER_AW_PRINT_WEB_VIEW_HELPER_DELEGATE_H_ + +#include "components/printing/renderer/print_web_view_helper.h" + +namespace android_webview { + +class AwPrintWebViewHelperDelegate + : public printing::PrintWebViewHelper::Delegate { + public: + ~AwPrintWebViewHelperDelegate() override; + bool CancelPrerender(content::RenderView* render_view, + int routing_id) override; + blink::WebElement GetPdfElement(blink::WebLocalFrame* frame) override; + bool IsOutOfProcessPdfEnabled() override; + bool IsPrintPreviewEnabled() override; + bool IsAskPrintSettingsEnabled() override; + bool IsScriptedPrintEnabled() override; + bool OverridePrint(blink::WebLocalFrame* frame) override; +}; // class AwPrintWebViewHelperDelegate + +} // namespace android_webview + +#endif // ANDROID_WEBVIEW_RENDERER_AW_PRINT_WEB_VIEW_HELPER_DELEGATE_H_ diff --git a/android_webview/renderer/print_render_frame_observer.cc b/android_webview/renderer/print_render_frame_observer.cc index d59c002..1e4b6c6 100644 --- a/android_webview/renderer/print_render_frame_observer.cc +++ b/android_webview/renderer/print_render_frame_observer.cc @@ -4,8 +4,8 @@ #include "android_webview/renderer/print_render_frame_observer.h" -#include "android_webview/common/print_messages.h" -#include "android_webview/renderer/print_web_view_helper.h" +#include "components/printing/common/print_messages.h" +#include "components/printing/renderer/print_web_view_helper.h" #include "content/public/renderer/render_frame.h" namespace android_webview { diff --git a/android_webview/renderer/print_web_view_helper.cc b/android_webview/renderer/print_web_view_helper.cc deleted file mode 100644 index a9727ef..0000000 --- a/android_webview/renderer/print_web_view_helper.cc +++ /dev/null @@ -1,2021 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// TODO(sgurun) copied from chrome/renderer. Remove after crbug.com/322276 - -#include "android_webview/renderer/print_web_view_helper.h" - -#include <string> - -#include "android_webview/common/print_messages.h" -#include "base/auto_reset.h" -#include "base/command_line.h" -#include "base/json/json_writer.h" -#include "base/logging.h" -#include "base/message_loop/message_loop.h" -#include "base/metrics/histogram.h" -#include "base/process/process_handle.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "content/public/common/web_preferences.h" -#include "content/public/renderer/render_thread.h" -#include "content/public/renderer/render_view.h" -#include "net/base/escape.h" -#include "printing/pdf_metafile_skia.h" -#include "printing/units.h" -#include "third_party/WebKit/public/platform/WebSize.h" -#include "third_party/WebKit/public/platform/WebURLRequest.h" -#include "third_party/WebKit/public/web/WebConsoleMessage.h" -#include "third_party/WebKit/public/web/WebDocument.h" -#include "third_party/WebKit/public/web/WebElement.h" -#include "third_party/WebKit/public/web/WebFrameClient.h" -#include "third_party/WebKit/public/web/WebLocalFrame.h" -#include "third_party/WebKit/public/web/WebPlugin.h" -#include "third_party/WebKit/public/web/WebPluginDocument.h" -#include "third_party/WebKit/public/web/WebPrintParams.h" -#include "third_party/WebKit/public/web/WebPrintScalingOption.h" -#include "third_party/WebKit/public/web/WebSandboxFlags.h" -#include "third_party/WebKit/public/web/WebScriptSource.h" -#include "third_party/WebKit/public/web/WebSettings.h" -#include "third_party/WebKit/public/web/WebView.h" -#include "third_party/WebKit/public/web/WebViewClient.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" - -// This code is copied from chrome/renderer/printing. Code is slightly -// modified to run it with webview, and the modifications are marked -// using OS_ANDROID. -// TODO(sgurun): remove the code as part of componentization of printing. - -using content::WebPreferences; - -namespace printing { - -namespace { - -enum PrintPreviewHelperEvents { - PREVIEW_EVENT_REQUESTED, - PREVIEW_EVENT_CACHE_HIT, // Unused - PREVIEW_EVENT_CREATE_DOCUMENT, - PREVIEW_EVENT_NEW_SETTINGS, // Unused - PREVIEW_EVENT_MAX, -}; - -const double kMinDpi = 1.0; - -#if 0 -// TODO(sgurun) android_webview hack -const char kPageLoadScriptFormat[] = - "document.open(); document.write(%s); document.close();"; - -const char kPageSetupScriptFormat[] = "setup(%s);"; - -void ExecuteScript(blink::WebFrame* frame, - const char* script_format, - const base::Value& parameters) { - std::string json; - base::JSONWriter::Write(¶meters, &json); - std::string script = base::StringPrintf(script_format, json.c_str()); - frame->executeScript(blink::WebString(base::UTF8ToUTF16(script))); -} -#endif - -int GetDPI(const PrintMsg_Print_Params* print_params) { -#if defined(OS_MACOSX) - // On the Mac, the printable area is in points, don't do any scaling based - // on dpi. - return kPointsPerInch; -#else - return static_cast<int>(print_params->dpi); -#endif // defined(OS_MACOSX) -} - -bool PrintMsg_Print_Params_IsValid(const PrintMsg_Print_Params& params) { - return !params.content_size.IsEmpty() && !params.page_size.IsEmpty() && - !params.printable_area.IsEmpty() && params.document_cookie && - params.desired_dpi && params.max_shrink && params.min_shrink && - params.dpi && (params.margin_top >= 0) && (params.margin_left >= 0); -} - -PrintMsg_Print_Params GetCssPrintParams( - blink::WebFrame* frame, - int page_index, - const PrintMsg_Print_Params& page_params) { - PrintMsg_Print_Params page_css_params = page_params; - int dpi = GetDPI(&page_params); - - blink::WebSize page_size_in_pixels( - ConvertUnit(page_params.page_size.width(), dpi, kPixelsPerInch), - ConvertUnit(page_params.page_size.height(), dpi, kPixelsPerInch)); - int margin_top_in_pixels = - ConvertUnit(page_params.margin_top, dpi, kPixelsPerInch); - int margin_right_in_pixels = ConvertUnit( - page_params.page_size.width() - - page_params.content_size.width() - page_params.margin_left, - dpi, kPixelsPerInch); - int margin_bottom_in_pixels = ConvertUnit( - page_params.page_size.height() - - page_params.content_size.height() - page_params.margin_top, - dpi, kPixelsPerInch); - int margin_left_in_pixels = ConvertUnit( - page_params.margin_left, - dpi, kPixelsPerInch); - - blink::WebSize original_page_size_in_pixels = page_size_in_pixels; - - if (frame) { - frame->pageSizeAndMarginsInPixels(page_index, - page_size_in_pixels, - margin_top_in_pixels, - margin_right_in_pixels, - margin_bottom_in_pixels, - margin_left_in_pixels); - } - - int new_content_width = page_size_in_pixels.width - - margin_left_in_pixels - margin_right_in_pixels; - int new_content_height = page_size_in_pixels.height - - margin_top_in_pixels - margin_bottom_in_pixels; - - // Invalid page size and/or margins. We just use the default setting. - if (new_content_width < 1 || new_content_height < 1) { - CHECK(frame); - page_css_params = GetCssPrintParams(NULL, page_index, page_params); - return page_css_params; - } - - page_css_params.content_size = gfx::Size( - ConvertUnit(new_content_width, kPixelsPerInch, dpi), - ConvertUnit(new_content_height, kPixelsPerInch, dpi)); - - if (original_page_size_in_pixels != page_size_in_pixels) { - page_css_params.page_size = gfx::Size( - ConvertUnit(page_size_in_pixels.width, kPixelsPerInch, dpi), - ConvertUnit(page_size_in_pixels.height, kPixelsPerInch, dpi)); - } else { - // Printing frame doesn't have any page size css. Pixels to dpi conversion - // causes rounding off errors. Therefore use the default page size values - // directly. - page_css_params.page_size = page_params.page_size; - } - - page_css_params.margin_top = - ConvertUnit(margin_top_in_pixels, kPixelsPerInch, dpi); - page_css_params.margin_left = - ConvertUnit(margin_left_in_pixels, kPixelsPerInch, dpi); - return page_css_params; -} - -double FitPrintParamsToPage(const PrintMsg_Print_Params& page_params, - PrintMsg_Print_Params* params_to_fit) { - double content_width = - static_cast<double>(params_to_fit->content_size.width()); - double content_height = - static_cast<double>(params_to_fit->content_size.height()); - int default_page_size_height = page_params.page_size.height(); - int default_page_size_width = page_params.page_size.width(); - int css_page_size_height = params_to_fit->page_size.height(); - int css_page_size_width = params_to_fit->page_size.width(); - - double scale_factor = 1.0f; - if (page_params.page_size == params_to_fit->page_size) - return scale_factor; - - if (default_page_size_width < css_page_size_width || - default_page_size_height < css_page_size_height) { - double ratio_width = - static_cast<double>(default_page_size_width) / css_page_size_width; - double ratio_height = - static_cast<double>(default_page_size_height) / css_page_size_height; - scale_factor = ratio_width < ratio_height ? ratio_width : ratio_height; - content_width *= scale_factor; - content_height *= scale_factor; - } - params_to_fit->margin_top = static_cast<int>( - (default_page_size_height - css_page_size_height * scale_factor) / 2 + - (params_to_fit->margin_top * scale_factor)); - params_to_fit->margin_left = static_cast<int>( - (default_page_size_width - css_page_size_width * scale_factor) / 2 + - (params_to_fit->margin_left * scale_factor)); - params_to_fit->content_size = gfx::Size( - static_cast<int>(content_width), static_cast<int>(content_height)); - params_to_fit->page_size = page_params.page_size; - return scale_factor; -} - -void CalculatePageLayoutFromPrintParams( - const PrintMsg_Print_Params& params, - PageSizeMargins* page_layout_in_points) { - int dpi = GetDPI(¶ms); - int content_width = params.content_size.width(); - int content_height = params.content_size.height(); - - int margin_bottom = params.page_size.height() - - content_height - params.margin_top; - int margin_right = params.page_size.width() - - content_width - params.margin_left; - - page_layout_in_points->content_width = - ConvertUnit(content_width, dpi, kPointsPerInch); - page_layout_in_points->content_height = - ConvertUnit(content_height, dpi, kPointsPerInch); - page_layout_in_points->margin_top = - ConvertUnit(params.margin_top, dpi, kPointsPerInch); - page_layout_in_points->margin_right = - ConvertUnit(margin_right, dpi, kPointsPerInch); - page_layout_in_points->margin_bottom = - ConvertUnit(margin_bottom, dpi, kPointsPerInch); - page_layout_in_points->margin_left = - ConvertUnit(params.margin_left, dpi, kPointsPerInch); -} - -void EnsureOrientationMatches(const PrintMsg_Print_Params& css_params, - PrintMsg_Print_Params* page_params) { - if ((page_params->page_size.width() > page_params->page_size.height()) == - (css_params.page_size.width() > css_params.page_size.height())) { - return; - } - - // Swap the |width| and |height| values. - page_params->page_size.SetSize(page_params->page_size.height(), - page_params->page_size.width()); - page_params->content_size.SetSize(page_params->content_size.height(), - page_params->content_size.width()); - page_params->printable_area.set_size( - gfx::Size(page_params->printable_area.height(), - page_params->printable_area.width())); -} - -void ComputeWebKitPrintParamsInDesiredDpi( - const PrintMsg_Print_Params& print_params, - blink::WebPrintParams* webkit_print_params) { - int dpi = GetDPI(&print_params); - webkit_print_params->printerDPI = dpi; - webkit_print_params->printScalingOption = print_params.print_scaling_option; - - webkit_print_params->printContentArea.width = - ConvertUnit(print_params.content_size.width(), dpi, - print_params.desired_dpi); - webkit_print_params->printContentArea.height = - ConvertUnit(print_params.content_size.height(), dpi, - print_params.desired_dpi); - - webkit_print_params->printableArea.x = - ConvertUnit(print_params.printable_area.x(), dpi, - print_params.desired_dpi); - webkit_print_params->printableArea.y = - ConvertUnit(print_params.printable_area.y(), dpi, - print_params.desired_dpi); - webkit_print_params->printableArea.width = - ConvertUnit(print_params.printable_area.width(), dpi, - print_params.desired_dpi); - webkit_print_params->printableArea.height = - ConvertUnit(print_params.printable_area.height(), - dpi, print_params.desired_dpi); - - webkit_print_params->paperSize.width = - ConvertUnit(print_params.page_size.width(), dpi, - print_params.desired_dpi); - webkit_print_params->paperSize.height = - ConvertUnit(print_params.page_size.height(), dpi, - print_params.desired_dpi); -} - -blink::WebPlugin* GetPlugin(const blink::WebFrame* frame) { - return frame->document().isPluginDocument() ? - frame->document().to<blink::WebPluginDocument>().plugin() : NULL; -} - -bool PrintingNodeOrPdfFrame(const blink::WebFrame* frame, - const blink::WebNode& node) { - if (!node.isNull()) - return true; - blink::WebPlugin* plugin = GetPlugin(frame); - return plugin && plugin->supportsPaginatedPrint(); -} - -bool PrintingFrameHasPageSizeStyle(blink::WebFrame* frame, - int total_page_count) { - if (!frame) - return false; - bool frame_has_custom_page_size_style = false; - for (int i = 0; i < total_page_count; ++i) { - if (frame->hasCustomPageSizeStyle(i)) { - frame_has_custom_page_size_style = true; - break; - } - } - return frame_has_custom_page_size_style; -} - -MarginType GetMarginsForPdf(blink::WebFrame* frame, - const blink::WebNode& node) { - if (frame->isPrintScalingDisabledForPlugin(node)) - return NO_MARGINS; - else - return PRINTABLE_AREA_MARGINS; -} - -bool FitToPageEnabled(const base::DictionaryValue& job_settings) { - bool fit_to_paper_size = false; - if (!job_settings.GetBoolean(kSettingFitToPageEnabled, &fit_to_paper_size)) { - NOTREACHED(); - } - return fit_to_paper_size; -} - -PrintMsg_Print_Params CalculatePrintParamsForCss( - blink::WebFrame* frame, - int page_index, - const PrintMsg_Print_Params& page_params, - bool ignore_css_margins, - bool fit_to_page, - double* scale_factor) { - PrintMsg_Print_Params css_params = GetCssPrintParams(frame, page_index, - page_params); - - PrintMsg_Print_Params params = page_params; - EnsureOrientationMatches(css_params, ¶ms); - - if (ignore_css_margins && fit_to_page) - return params; - - PrintMsg_Print_Params result_params = css_params; - if (ignore_css_margins) { - result_params.margin_top = params.margin_top; - result_params.margin_left = params.margin_left; - - DCHECK(!fit_to_page); - // Since we are ignoring the margins, the css page size is no longer - // valid. - int default_margin_right = params.page_size.width() - - params.content_size.width() - params.margin_left; - int default_margin_bottom = params.page_size.height() - - params.content_size.height() - params.margin_top; - result_params.content_size = gfx::Size( - result_params.page_size.width() - result_params.margin_left - - default_margin_right, - result_params.page_size.height() - result_params.margin_top - - default_margin_bottom); - } - - if (fit_to_page) { - double factor = FitPrintParamsToPage(params, &result_params); - if (scale_factor) - *scale_factor = factor; - } - return result_params; -} - -bool IsPrintPreviewEnabled() { - return false; -} - -bool IsPrintThrottlingDisabled() { - return true; -} - -} // namespace - -FrameReference::FrameReference(blink::WebLocalFrame* frame) { - Reset(frame); -} - -FrameReference::FrameReference() { - Reset(NULL); -} - -FrameReference::~FrameReference() { -} - -void FrameReference::Reset(blink::WebLocalFrame* frame) { - if (frame) { - view_ = frame->view(); - frame_ = frame; - } else { - view_ = NULL; - frame_ = NULL; - } -} - -blink::WebLocalFrame* FrameReference::GetFrame() { - if (view_ == NULL || frame_ == NULL) - return NULL; - for (blink::WebFrame* frame = view_->mainFrame(); frame != NULL; - frame = frame->traverseNext(false)) { - if (frame == frame_) - return frame_; - } - return NULL; -} - -blink::WebView* FrameReference::view() { - return view_; -} - -// static - Not anonymous so that platform implementations can use it. -void PrintWebViewHelper::PrintHeaderAndFooter( - blink::WebCanvas* canvas, - int page_number, - int total_pages, - float webkit_scale_factor, - const PageSizeMargins& page_layout, - const base::DictionaryValue& header_footer_info, - const PrintMsg_Print_Params& params) { -#if 0 - // TODO(sgurun) android_webview hack - SkAutoCanvasRestore auto_restore(canvas, true); - canvas->scale(1 / webkit_scale_factor, 1 / webkit_scale_factor); - - blink::WebSize page_size(page_layout.margin_left + page_layout.margin_right + - page_layout.content_width, - page_layout.margin_top + page_layout.margin_bottom + - page_layout.content_height); - - blink::WebView* web_view = blink::WebView::create(NULL); - web_view->settings()->setJavaScriptEnabled(true); - blink::WebFrame* frame = blink::WebLocalFrame::create(NULL) - web_view->setMainFrame(web_frame); - - base::StringValue html( - ResourceBundle::GetSharedInstance().GetLocalizedString( - IDR_PRINT_PREVIEW_PAGE)); - // Load page with script to avoid async operations. - ExecuteScript(frame, kPageLoadScriptFormat, html); - - scoped_ptr<base::DictionaryValue> options(header_footer_info.DeepCopy()); - options->SetDouble("width", page_size.width); - options->SetDouble("height", page_size.height); - options->SetDouble("topMargin", page_layout.margin_top); - options->SetDouble("bottomMargin", page_layout.margin_bottom); - options->SetString("pageNumber", - base::StringPrintf("%d/%d", page_number, total_pages)); - - ExecuteScript(frame, kPageSetupScriptFormat, *options); - - blink::WebPrintParams webkit_params(page_size); - webkit_params.printerDPI = GetDPI(¶ms); - - frame->printBegin(webkit_params, WebKit::WebNode(), NULL); - frame->printPage(0, canvas); - frame->printEnd(); - - web_view->close(); - frame->close(); -#endif -} - -// static - Not anonymous so that platform implementations can use it. -float PrintWebViewHelper::RenderPageContent(blink::WebFrame* frame, - int page_number, - const gfx::Rect& canvas_area, - const gfx::Rect& content_area, - double scale_factor, - blink::WebCanvas* canvas) { - SkAutoCanvasRestore auto_restore(canvas, true); - if (content_area != canvas_area) { - canvas->translate((content_area.x() - canvas_area.x()) / scale_factor, - (content_area.y() - canvas_area.y()) / scale_factor); - SkRect clip_rect( - SkRect::MakeXYWH(content_area.origin().x() / scale_factor, - content_area.origin().y() / scale_factor, - content_area.size().width() / scale_factor, - content_area.size().height() / scale_factor)); - SkIRect clip_int_rect; - clip_rect.roundOut(&clip_int_rect); - SkRegion clip_region(clip_int_rect); - canvas->setClipRegion(clip_region); - } - return frame->printPage(page_number, canvas); -} - -// Class that calls the Begin and End print functions on the frame and changes -// the size of the view temporarily to support full page printing.. -class PrepareFrameAndViewForPrint : public blink::WebViewClient, - public blink::WebFrameClient { - public: - PrepareFrameAndViewForPrint(const PrintMsg_Print_Params& params, - blink::WebLocalFrame* frame, - const blink::WebNode& node, - bool ignore_css_margins); - virtual ~PrepareFrameAndViewForPrint(); - - // Optional. Replaces |frame_| with selection if needed. Will call |on_ready| - // when completed. - void CopySelectionIfNeeded(const WebPreferences& preferences, - const base::Closure& on_ready); - - // Prepares frame for printing. - void StartPrinting(); - - blink::WebLocalFrame* frame() { - return frame_.GetFrame(); - } - - const blink::WebNode& node() const { - return node_to_print_; - } - - int GetExpectedPageCount() const { - return expected_pages_count_; - } - - gfx::Size GetPrintCanvasSize() const; - - void FinishPrinting(); - - bool IsLoadingSelection() { - // It's not selection if not |owns_web_view_|. - return owns_web_view_ && frame() && frame()->isLoading(); - } - - // TODO(ojan): Remove this override and have this class use a non-null - // layerTreeView. - // blink::WebViewClient override: - virtual bool allowsBrokenNullLayerTreeView() const; - - protected: - // blink::WebViewClient override: - virtual void didStopLoading(); - - // blink::WebFrameClient override: - virtual blink::WebFrame* createChildFrame( - blink::WebLocalFrame* parent, - const blink::WebString& name, - blink::WebSandboxFlags sandboxFlags); - virtual void frameDetached(blink::WebFrame* frame); - - private: - void CallOnReady(); - void ResizeForPrinting(); - void RestoreSize(); - void CopySelection(const WebPreferences& preferences); - - FrameReference frame_; - blink::WebNode node_to_print_; - bool owns_web_view_; - blink::WebPrintParams web_print_params_; - gfx::Size prev_view_size_; - gfx::Size prev_scroll_offset_; - int expected_pages_count_; - base::Closure on_ready_; - bool should_print_backgrounds_; - bool should_print_selection_only_; - bool is_printing_started_; - - base::WeakPtrFactory<PrepareFrameAndViewForPrint> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(PrepareFrameAndViewForPrint); -}; - -PrepareFrameAndViewForPrint::PrepareFrameAndViewForPrint( - const PrintMsg_Print_Params& params, - blink::WebLocalFrame* frame, - const blink::WebNode& node, - bool ignore_css_margins) - : frame_(frame), - node_to_print_(node), - owns_web_view_(false), - expected_pages_count_(0), - should_print_backgrounds_(params.should_print_backgrounds), - should_print_selection_only_(params.selection_only), - is_printing_started_(false), - weak_ptr_factory_(this) { - PrintMsg_Print_Params print_params = params; - if (!should_print_selection_only_ || - !PrintingNodeOrPdfFrame(frame, node_to_print_)) { - bool fit_to_page = ignore_css_margins && - print_params.print_scaling_option == - blink::WebPrintScalingOptionFitToPrintableArea; - ComputeWebKitPrintParamsInDesiredDpi(params, &web_print_params_); - frame->printBegin(web_print_params_, node_to_print_); - print_params = CalculatePrintParamsForCss(frame, 0, print_params, - ignore_css_margins, fit_to_page, - NULL); - frame->printEnd(); - } - ComputeWebKitPrintParamsInDesiredDpi(print_params, &web_print_params_); -} - -PrepareFrameAndViewForPrint::~PrepareFrameAndViewForPrint() { - FinishPrinting(); -} - -void PrepareFrameAndViewForPrint::ResizeForPrinting() { - // Layout page according to printer page size. Since WebKit shrinks the - // size of the page automatically (from 125% to 200%) we trick it to - // think the page is 125% larger so the size of the page is correct for - // minimum (default) scaling. - // This is important for sites that try to fill the page. - gfx::Size print_layout_size(web_print_params_.printContentArea.width, - web_print_params_.printContentArea.height); - print_layout_size.set_height( - static_cast<int>(static_cast<double>(print_layout_size.height()) * 1.25)); - - if (!frame()) - return; - blink::WebView* web_view = frame_.view(); - // Backup size and offset. - if (blink::WebFrame* web_frame = web_view->mainFrame()) - prev_scroll_offset_ = web_frame->scrollOffset(); - prev_view_size_ = web_view->size(); - - web_view->resize(print_layout_size); -} - - -void PrepareFrameAndViewForPrint::StartPrinting() { - ResizeForPrinting(); - blink::WebView* web_view = frame_.view(); - web_view->settings()->setShouldPrintBackgrounds(should_print_backgrounds_); - expected_pages_count_ = - frame()->printBegin(web_print_params_, node_to_print_); - is_printing_started_ = true; -} - -void PrepareFrameAndViewForPrint::CopySelectionIfNeeded( - const WebPreferences& preferences, - const base::Closure& on_ready) { - on_ready_ = on_ready; - if (should_print_selection_only_) - CopySelection(preferences); - else - didStopLoading(); -} - -void PrepareFrameAndViewForPrint::CopySelection( - const WebPreferences& preferences) { - ResizeForPrinting(); - std::string url_str = "data:text/html;charset=utf-8,"; - url_str.append( - net::EscapeQueryParamValue(frame()->selectionAsMarkup().utf8(), false)); - RestoreSize(); - // Create a new WebView with the same settings as the current display one. - // Except that we disable javascript (don't want any active content running - // on the page). - WebPreferences prefs = preferences; - prefs.javascript_enabled = false; - prefs.java_enabled = false; - - blink::WebView* web_view = blink::WebView::create(this); - owns_web_view_ = true; - content::RenderView::ApplyWebPreferences(prefs, web_view); - web_view->setMainFrame(blink::WebLocalFrame::create(this)); - frame_.Reset(web_view->mainFrame()->toWebLocalFrame()); - node_to_print_.reset(); - - // When loading is done this will call didStopLoading() and that will do the - // actual printing. - frame()->loadRequest(blink::WebURLRequest(GURL(url_str))); -} - -bool PrepareFrameAndViewForPrint::allowsBrokenNullLayerTreeView() const { - return true; -} - -void PrepareFrameAndViewForPrint::didStopLoading() { - DCHECK(!on_ready_.is_null()); - // Don't call callback here, because it can delete |this| and WebView that is - // called didStopLoading. - base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&PrepareFrameAndViewForPrint::CallOnReady, - weak_ptr_factory_.GetWeakPtr())); -} - -blink::WebFrame* PrepareFrameAndViewForPrint::createChildFrame( - blink::WebLocalFrame* parent, - const blink::WebString& name, - blink::WebSandboxFlags sandboxFlags) { - blink::WebFrame* frame = blink::WebLocalFrame::create(this); - parent->appendChild(frame); - return frame; -} - -void PrepareFrameAndViewForPrint::frameDetached(blink::WebFrame* frame) { - if (frame->parent()) - frame->parent()->removeChild(frame); - frame->close(); -} - -void PrepareFrameAndViewForPrint::CallOnReady() { - return on_ready_.Run(); // Can delete |this|. -} - -gfx::Size PrepareFrameAndViewForPrint::GetPrintCanvasSize() const { - DCHECK(is_printing_started_); - return gfx::Size(web_print_params_.printContentArea.width, - web_print_params_.printContentArea.height); -} - -void PrepareFrameAndViewForPrint::RestoreSize() { - if (frame()) { - blink::WebView* web_view = frame_.GetFrame()->view(); - web_view->resize(prev_view_size_); - if (blink::WebFrame* web_frame = web_view->mainFrame()) - web_frame->setScrollOffset(prev_scroll_offset_); - } -} - -void PrepareFrameAndViewForPrint::FinishPrinting() { - blink::WebLocalFrame* frame = frame_.GetFrame(); - if (frame) { - blink::WebView* web_view = frame->view(); - if (is_printing_started_) { - is_printing_started_ = false; - frame->printEnd(); - if (!owns_web_view_) { - web_view->settings()->setShouldPrintBackgrounds(false); - RestoreSize(); - } - } - if (owns_web_view_) { - DCHECK(!frame->isLoading()); - owns_web_view_ = false; - web_view->close(); - } - } - frame_.Reset(NULL); - on_ready_.Reset(); -} - -PrintWebViewHelper::PrintWebViewHelper(content::RenderView* render_view) - : content::RenderViewObserver(render_view), - content::RenderViewObserverTracker<PrintWebViewHelper>(render_view), - reset_prep_frame_view_(false), - is_preview_enabled_(IsPrintPreviewEnabled()), - is_scripted_print_throttling_disabled_(IsPrintThrottlingDisabled()), - is_print_ready_metafile_sent_(false), - ignore_css_margins_(false), - user_cancelled_scripted_print_count_(0), - is_scripted_printing_blocked_(false), - notify_browser_of_print_failure_(true), - print_for_preview_(false), - print_node_in_progress_(false), - is_loading_(false), - is_scripted_preview_delayed_(false), - weak_ptr_factory_(this) { - // TODO(sgurun) enable window.print() for webview crbug.com/322303 - SetScriptedPrintBlocked(true); -} - -PrintWebViewHelper::~PrintWebViewHelper() {} - -bool PrintWebViewHelper::IsScriptInitiatedPrintAllowed( - blink::WebFrame* frame, bool user_initiated) { -#if defined(OS_ANDROID) - return false; -#endif // defined(OS_ANDROID) - if (is_scripted_printing_blocked_) - return false; - // If preview is enabled, then the print dialog is tab modal, and the user - // can always close the tab on a mis-behaving page (the system print dialog - // is app modal). If the print was initiated through user action, don't - // throttle. Or, if the command line flag to skip throttling has been set. - if (!is_scripted_print_throttling_disabled_ && - !is_preview_enabled_ && - !user_initiated) - return !IsScriptInitiatedPrintTooFrequent(frame); - return true; -} - -void PrintWebViewHelper::DidStartLoading() { - is_loading_ = true; -} - -void PrintWebViewHelper::DidStopLoading() { - is_loading_ = false; - ShowScriptedPrintPreview(); -} - -// Prints |frame| which called window.print(). -void PrintWebViewHelper::PrintPage(blink::WebLocalFrame* frame, - bool user_initiated) { - DCHECK(frame); - -#if !defined(OS_ANDROID) - // TODO(sgurun) android_webview hack - // Allow Prerendering to cancel this print request if necessary. - if (prerender::PrerenderHelper::IsPrerendering(render_view())) { - Send(new ChromeViewHostMsg_CancelPrerenderForPrinting(routing_id())); - return; - } -#endif // !defined(OS_ANDROID) - - if (!IsScriptInitiatedPrintAllowed(frame, user_initiated)) - return; - IncrementScriptedPrintCount(); - - if (is_preview_enabled_) { - print_preview_context_.InitWithFrame(frame); - RequestPrintPreview(PRINT_PREVIEW_SCRIPTED); - } else { - Print(frame, blink::WebNode()); - } -} - -bool PrintWebViewHelper::OnMessageReceived(const IPC::Message& message) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(PrintWebViewHelper, message) - IPC_MESSAGE_HANDLER(PrintMsg_PrintPages, OnPrintPages) - IPC_MESSAGE_HANDLER(PrintMsg_PrintForSystemDialog, OnPrintForSystemDialog) - IPC_MESSAGE_HANDLER(PrintMsg_InitiatePrintPreview, OnInitiatePrintPreview) - IPC_MESSAGE_HANDLER(PrintMsg_PrintPreview, OnPrintPreview) - IPC_MESSAGE_HANDLER(PrintMsg_PrintForPrintPreview, OnPrintForPrintPreview) - IPC_MESSAGE_HANDLER(PrintMsg_PrintingDone, OnPrintingDone) - IPC_MESSAGE_HANDLER(PrintMsg_ResetScriptedPrintCount, - ResetScriptedPrintCount) - IPC_MESSAGE_HANDLER(PrintMsg_SetScriptedPrintingBlocked, - SetScriptedPrintBlocked) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - -void PrintWebViewHelper::OnPrintForPrintPreview( - const base::DictionaryValue& job_settings) { - DCHECK(is_preview_enabled_); - // If still not finished with earlier print request simply ignore. - if (prep_frame_view_) - return; - - if (!render_view()->GetWebView()) - return; - blink::WebFrame* main_frame = render_view()->GetWebView()->mainFrame(); - if (!main_frame) - return; - - blink::WebDocument document = main_frame->document(); - // <object> with id="pdf-viewer" is created in - // chrome/browser/resources/print_preview/print_preview.js - blink::WebElement pdf_element = document.getElementById("pdf-viewer"); - if (pdf_element.isNull()) { - NOTREACHED(); - return; - } - - // Set |print_for_preview_| flag and autoreset it to back to original - // on return. - base::AutoReset<bool> set_printing_flag(&print_for_preview_, true); - - blink::WebLocalFrame* pdf_frame = pdf_element.document().frame(); - if (!UpdatePrintSettings(pdf_frame, pdf_element, job_settings)) { - LOG(ERROR) << "UpdatePrintSettings failed"; - DidFinishPrinting(FAIL_PRINT); - return; - } - - // Print page onto entire page not just printable area. Preview PDF already - // has content in correct position taking into account page size and printable - // area. - // TODO(vitalybuka) : Make this consistent on all platform. This change - // affects Windows only. On Linux and OSX RenderPagesForPrint does not use - // printable_area. Also we can't change printable_area deeper inside - // RenderPagesForPrint for Windows, because it's used also by native - // printing and it expects real printable_area value. - // See http://crbug.com/123408 - PrintMsg_Print_Params& print_params = print_pages_params_->params; - print_params.printable_area = gfx::Rect(print_params.page_size); - - // Render Pages for printing. - if (!RenderPagesForPrint(pdf_frame, pdf_element)) { - LOG(ERROR) << "RenderPagesForPrint failed"; - DidFinishPrinting(FAIL_PRINT); - } -} - -bool PrintWebViewHelper::GetPrintFrame(blink::WebLocalFrame** frame) { - DCHECK(frame); - blink::WebView* webView = render_view()->GetWebView(); - DCHECK(webView); - if (!webView) - return false; - - // If the user has selected text in the currently focused frame we print - // only that frame (this makes print selection work for multiple frames). - blink::WebLocalFrame* focusedFrame = - webView->focusedFrame()->toWebLocalFrame(); - *frame = focusedFrame->hasSelection() - ? focusedFrame - : webView->mainFrame()->toWebLocalFrame(); - return true; -} - -void PrintWebViewHelper::OnPrintPages() { - blink::WebLocalFrame* frame; - if (GetPrintFrame(&frame)) - Print(frame, blink::WebNode()); -} - -void PrintWebViewHelper::OnPrintForSystemDialog() { - blink::WebLocalFrame* frame = print_preview_context_.source_frame(); - if (!frame) { - NOTREACHED(); - return; - } - - Print(frame, print_preview_context_.source_node()); -} - -void PrintWebViewHelper::GetPageSizeAndContentAreaFromPageLayout( - const PageSizeMargins& page_layout_in_points, - gfx::Size* page_size, - gfx::Rect* content_area) { - *page_size = gfx::Size( - page_layout_in_points.content_width + - page_layout_in_points.margin_right + - page_layout_in_points.margin_left, - page_layout_in_points.content_height + - page_layout_in_points.margin_top + - page_layout_in_points.margin_bottom); - *content_area = gfx::Rect(page_layout_in_points.margin_left, - page_layout_in_points.margin_top, - page_layout_in_points.content_width, - page_layout_in_points.content_height); -} - -void PrintWebViewHelper::UpdateFrameMarginsCssInfo( - const base::DictionaryValue& settings) { - int margins_type = 0; - if (!settings.GetInteger(kSettingMarginsType, &margins_type)) - margins_type = DEFAULT_MARGINS; - ignore_css_margins_ = (margins_type != DEFAULT_MARGINS); -} - -bool PrintWebViewHelper::IsPrintToPdfRequested( - const base::DictionaryValue& job_settings) { - bool print_to_pdf = false; - if (!job_settings.GetBoolean(kSettingPrintToPDF, &print_to_pdf)) - NOTREACHED(); - return print_to_pdf; -} - -blink::WebPrintScalingOption PrintWebViewHelper::GetPrintScalingOption( - bool source_is_html, const base::DictionaryValue& job_settings, - const PrintMsg_Print_Params& params) { - DCHECK(!print_for_preview_); - - if (params.print_to_pdf) - return blink::WebPrintScalingOptionSourceSize; - - if (!source_is_html) { - if (!FitToPageEnabled(job_settings)) - return blink::WebPrintScalingOptionNone; - - bool no_plugin_scaling = - print_preview_context_.source_frame()->isPrintScalingDisabledForPlugin( - print_preview_context_.source_node()); - - if (params.is_first_request && no_plugin_scaling) - return blink::WebPrintScalingOptionNone; - } - return blink::WebPrintScalingOptionFitToPrintableArea; -} - -void PrintWebViewHelper::OnPrintPreview(const base::DictionaryValue& settings) { - DCHECK(is_preview_enabled_); - print_preview_context_.OnPrintPreview(); - - UMA_HISTOGRAM_ENUMERATION("PrintPreview.PreviewEvent", - PREVIEW_EVENT_REQUESTED, PREVIEW_EVENT_MAX); - - if (!UpdatePrintSettings(print_preview_context_.source_frame(), - print_preview_context_.source_node(), settings)) { - if (print_preview_context_.last_error() != PREVIEW_ERROR_BAD_SETTING) { - Send(new PrintHostMsg_PrintPreviewInvalidPrinterSettings( - routing_id(), print_pages_params_->params.document_cookie)); - notify_browser_of_print_failure_ = false; // Already sent. - } - DidFinishPrinting(FAIL_PREVIEW); - return; - } - - // If we are previewing a pdf and the print scaling is disabled, send a - // message to browser. - if (print_pages_params_->params.is_first_request && - !print_preview_context_.IsModifiable() && - print_preview_context_.source_frame()->isPrintScalingDisabledForPlugin( - print_preview_context_.source_node())) { - Send(new PrintHostMsg_PrintPreviewScalingDisabled(routing_id())); - } - - is_print_ready_metafile_sent_ = false; - - // PDF printer device supports alpha blending. - print_pages_params_->params.supports_alpha_blend = true; - - bool generate_draft_pages = false; - if (!settings.GetBoolean(kSettingGenerateDraftData, - &generate_draft_pages)) { - NOTREACHED(); - } - print_preview_context_.set_generate_draft_pages(generate_draft_pages); - - PrepareFrameForPreviewDocument(); -} - -void PrintWebViewHelper::PrepareFrameForPreviewDocument() { - reset_prep_frame_view_ = false; - - if (!print_pages_params_ || CheckForCancel()) { - DidFinishPrinting(FAIL_PREVIEW); - return; - } - - // Don't reset loading frame or WebKit will fail assert. Just retry when - // current selection is loaded. - if (prep_frame_view_ && prep_frame_view_->IsLoadingSelection()) { - reset_prep_frame_view_ = true; - return; - } - - const PrintMsg_Print_Params& print_params = print_pages_params_->params; - prep_frame_view_.reset( - new PrepareFrameAndViewForPrint(print_params, - print_preview_context_.source_frame(), - print_preview_context_.source_node(), - ignore_css_margins_)); - prep_frame_view_->CopySelectionIfNeeded( - render_view()->GetWebkitPreferences(), - base::Bind(&PrintWebViewHelper::OnFramePreparedForPreviewDocument, - base::Unretained(this))); -} - -void PrintWebViewHelper::OnFramePreparedForPreviewDocument() { - if (reset_prep_frame_view_) { - PrepareFrameForPreviewDocument(); - return; - } - DidFinishPrinting(CreatePreviewDocument() ? OK : FAIL_PREVIEW); -} - -bool PrintWebViewHelper::CreatePreviewDocument() { - if (!print_pages_params_ || CheckForCancel()) - return false; - - UMA_HISTOGRAM_ENUMERATION("PrintPreview.PreviewEvent", - PREVIEW_EVENT_CREATE_DOCUMENT, PREVIEW_EVENT_MAX); - - const PrintMsg_Print_Params& print_params = print_pages_params_->params; - const std::vector<int>& pages = print_pages_params_->pages; - - if (!print_preview_context_.CreatePreviewDocument(prep_frame_view_.release(), - pages)) { - return false; - } - - PageSizeMargins default_page_layout; - ComputePageLayoutInPointsForCss(print_preview_context_.prepared_frame(), 0, - print_params, ignore_css_margins_, NULL, - &default_page_layout); - - bool has_page_size_style = PrintingFrameHasPageSizeStyle( - print_preview_context_.prepared_frame(), - print_preview_context_.total_page_count()); - int dpi = GetDPI(&print_params); - - gfx::Rect printable_area_in_points( - ConvertUnit(print_params.printable_area.x(), dpi, kPointsPerInch), - ConvertUnit(print_params.printable_area.y(), dpi, kPointsPerInch), - ConvertUnit(print_params.printable_area.width(), dpi, kPointsPerInch), - ConvertUnit(print_params.printable_area.height(), dpi, kPointsPerInch)); - - // Margins: Send default page layout to browser process. - Send(new PrintHostMsg_DidGetDefaultPageLayout(routing_id(), - default_page_layout, - printable_area_in_points, - has_page_size_style)); - - PrintHostMsg_DidGetPreviewPageCount_Params params; - params.page_count = print_preview_context_.total_page_count(); - params.is_modifiable = print_preview_context_.IsModifiable(); - params.document_cookie = print_params.document_cookie; - params.preview_request_id = print_params.preview_request_id; - params.clear_preview_data = print_preview_context_.generate_draft_pages(); - Send(new PrintHostMsg_DidGetPreviewPageCount(routing_id(), params)); - if (CheckForCancel()) - return false; - - while (!print_preview_context_.IsFinalPageRendered()) { - int page_number = print_preview_context_.GetNextPageNumber(); - DCHECK_GE(page_number, 0); - if (!RenderPreviewPage(page_number, print_params)) - return false; - - if (CheckForCancel()) - return false; - - // We must call PrepareFrameAndViewForPrint::FinishPrinting() (by way of - // print_preview_context_.AllPagesRendered()) before calling - // FinalizePrintReadyDocument() when printing a PDF because the plugin - // code does not generate output until we call FinishPrinting(). We do not - // generate draft pages for PDFs, so IsFinalPageRendered() and - // IsLastPageOfPrintReadyMetafile() will be true in the same iteration of - // the loop. - if (print_preview_context_.IsFinalPageRendered()) - print_preview_context_.AllPagesRendered(); - - if (print_preview_context_.IsLastPageOfPrintReadyMetafile()) { - DCHECK(print_preview_context_.IsModifiable() || - print_preview_context_.IsFinalPageRendered()); - if (!FinalizePrintReadyDocument()) - return false; - } - } - print_preview_context_.Finished(); - return true; -} - -bool PrintWebViewHelper::FinalizePrintReadyDocument() { - DCHECK(!is_print_ready_metafile_sent_); - print_preview_context_.FinalizePrintReadyDocument(); - - // Get the size of the resulting metafile. - PdfMetafileSkia* metafile = print_preview_context_.metafile(); - uint32 buf_size = metafile->GetDataSize(); - DCHECK_GT(buf_size, 0u); - - PrintHostMsg_DidPreviewDocument_Params preview_params; - preview_params.reuse_existing_data = false; - preview_params.data_size = buf_size; - preview_params.document_cookie = print_pages_params_->params.document_cookie; - preview_params.expected_pages_count = - print_preview_context_.total_page_count(); - preview_params.modifiable = print_preview_context_.IsModifiable(); - preview_params.preview_request_id = - print_pages_params_->params.preview_request_id; - - // Ask the browser to create the shared memory for us. - if (!CopyMetafileDataToSharedMem(metafile, - &(preview_params.metafile_data_handle))) { - LOG(ERROR) << "CopyMetafileDataToSharedMem failed"; - print_preview_context_.set_error(PREVIEW_ERROR_METAFILE_COPY_FAILED); - return false; - } - is_print_ready_metafile_sent_ = true; - - Send(new PrintHostMsg_MetafileReadyForPrinting(routing_id(), preview_params)); - return true; -} - -void PrintWebViewHelper::OnPrintingDone(bool success) { - notify_browser_of_print_failure_ = false; - if (!success) - LOG(ERROR) << "Failure in OnPrintingDone"; - DidFinishPrinting(success ? OK : FAIL_PRINT); -} - -void PrintWebViewHelper::SetScriptedPrintBlocked(bool blocked) { - is_scripted_printing_blocked_ = blocked; -} - -void PrintWebViewHelper::OnInitiatePrintPreview(bool selection_only) { - DCHECK(is_preview_enabled_); - blink::WebLocalFrame* frame = NULL; - GetPrintFrame(&frame); - DCHECK(frame); - print_preview_context_.InitWithFrame(frame); - RequestPrintPreview(selection_only ? - PRINT_PREVIEW_USER_INITIATED_SELECTION : - PRINT_PREVIEW_USER_INITIATED_ENTIRE_FRAME); -} - -bool PrintWebViewHelper::IsPrintingEnabled() { - bool result = false; - Send(new PrintHostMsg_IsPrintingEnabled(routing_id(), &result)); - return result; -} - -void PrintWebViewHelper::PrintNode(const blink::WebNode& node) { - if (node.isNull() || !node.document().frame()) { - // This can occur when the context menu refers to an invalid WebNode. - // See http://crbug.com/100890#c17 for a repro case. - return; - } - - if (print_node_in_progress_) { - // This can happen as a result of processing sync messages when printing - // from ppapi plugins. It's a rare case, so its OK to just fail here. - // See http://crbug.com/159165. - return; - } - - print_node_in_progress_ = true; - - // Make a copy of the node, in case RenderView::OnContextMenuClosed resets - // its |context_menu_node_|. - if (is_preview_enabled_) { - print_preview_context_.InitWithNode(node); - RequestPrintPreview(PRINT_PREVIEW_USER_INITIATED_CONTEXT_NODE); - } else { - blink::WebNode duplicate_node(node); - Print(duplicate_node.document().frame(), duplicate_node); - } - - print_node_in_progress_ = false; -} - -void PrintWebViewHelper::Print(blink::WebLocalFrame* frame, - const blink::WebNode& node) { - // If still not finished with earlier print request simply ignore. - if (prep_frame_view_) - return; - - FrameReference frame_ref(frame); - - int expected_page_count = 0; - if (!CalculateNumberOfPages(frame, node, &expected_page_count)) { - DidFinishPrinting(FAIL_PRINT_INIT); - return; // Failed to init print page settings. - } - - // Some full screen plugins can say they don't want to print. - if (!expected_page_count) { - DidFinishPrinting(FAIL_PRINT); - return; - } - -#if !defined(OS_ANDROID) - // TODO(sgurun) android_webview hack - // Ask the browser to show UI to retrieve the final print settings. - if (!GetPrintSettingsFromUser(frame_ref.GetFrame(), node, - expected_page_count)) { - DidFinishPrinting(OK); // Release resources and fail silently. - return; - } -#endif // !defined(OS_ANDROID) - - // Render Pages for printing. - if (!RenderPagesForPrint(frame_ref.GetFrame(), node)) { - LOG(ERROR) << "RenderPagesForPrint failed"; - DidFinishPrinting(FAIL_PRINT); - } - ResetScriptedPrintCount(); -} - -void PrintWebViewHelper::DidFinishPrinting(PrintingResult result) { - switch (result) { - case OK: - break; - - case FAIL_PRINT_INIT: - DCHECK(!notify_browser_of_print_failure_); - break; - - case FAIL_PRINT: - if (notify_browser_of_print_failure_ && print_pages_params_.get()) { - int cookie = print_pages_params_->params.document_cookie; - Send(new PrintHostMsg_PrintingFailed(routing_id(), cookie)); - } - break; - - case FAIL_PREVIEW: - DCHECK(is_preview_enabled_); - int cookie = print_pages_params_.get() ? - print_pages_params_->params.document_cookie : 0; - if (notify_browser_of_print_failure_) { - LOG(ERROR) << "CreatePreviewDocument failed"; - Send(new PrintHostMsg_PrintPreviewFailed(routing_id(), cookie)); - } else { - Send(new PrintHostMsg_PrintPreviewCancelled(routing_id(), cookie)); - } - print_preview_context_.Failed(notify_browser_of_print_failure_); - break; - } - - prep_frame_view_.reset(); - print_pages_params_.reset(); - notify_browser_of_print_failure_ = true; -} - -void PrintWebViewHelper::OnFramePreparedForPrintPages() { - PrintPages(); - FinishFramePrinting(); -} - -void PrintWebViewHelper::PrintPages() { - if (!prep_frame_view_) // Printing is already canceled or failed. - return; - prep_frame_view_->StartPrinting(); - - int page_count = prep_frame_view_->GetExpectedPageCount(); - if (!page_count) { - LOG(ERROR) << "Can't print 0 pages."; - return DidFinishPrinting(FAIL_PRINT); - } - - const PrintMsg_PrintPages_Params& params = *print_pages_params_; - const PrintMsg_Print_Params& print_params = params.params; - -#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) - // TODO(vitalybuka): should be page_count or valid pages from params.pages. - // See http://crbug.com/161576 - Send(new PrintHostMsg_DidGetPrintedPagesCount(routing_id(), - print_params.document_cookie, - page_count)); -#endif // !defined(OS_CHROMEOS) - - if (print_params.preview_ui_id < 0) { - // Printing for system dialog. - int printed_count = params.pages.empty() ? page_count : params.pages.size(); -#if !defined(OS_CHROMEOS) - UMA_HISTOGRAM_COUNTS("PrintPreview.PageCount.SystemDialog", printed_count); -#else - UMA_HISTOGRAM_COUNTS("PrintPreview.PageCount.PrintToCloudPrintWebDialog", - printed_count); -#endif // !defined(OS_CHROMEOS) - } - - - if (!PrintPagesNative(prep_frame_view_->frame(), page_count, - prep_frame_view_->GetPrintCanvasSize())) { - LOG(ERROR) << "Printing failed."; - return DidFinishPrinting(FAIL_PRINT); - } -} - -void PrintWebViewHelper::FinishFramePrinting() { - prep_frame_view_.reset(); -} - -#if defined(OS_MACOSX) || defined(OS_WIN) -bool PrintWebViewHelper::PrintPagesNative(blink::WebFrame* frame, - int page_count, - const gfx::Size& canvas_size) { - const PrintMsg_PrintPages_Params& params = *print_pages_params_; - const PrintMsg_Print_Params& print_params = params.params; - - PrintMsg_PrintPage_Params page_params; - page_params.params = print_params; - if (params.pages.empty()) { - for (int i = 0; i < page_count; ++i) { - page_params.page_number = i; - PrintPageInternal(page_params, canvas_size, frame); - } - } else { - for (size_t i = 0; i < params.pages.size(); ++i) { - if (params.pages[i] >= page_count) - break; - page_params.page_number = params.pages[i]; - PrintPageInternal(page_params, canvas_size, frame); - } - } - return true; -} - -#endif // OS_MACOSX || OS_WIN - -// static - Not anonymous so that platform implementations can use it. -void PrintWebViewHelper::ComputePageLayoutInPointsForCss( - blink::WebFrame* frame, - int page_index, - const PrintMsg_Print_Params& page_params, - bool ignore_css_margins, - double* scale_factor, - PageSizeMargins* page_layout_in_points) { - PrintMsg_Print_Params params = CalculatePrintParamsForCss( - frame, page_index, page_params, ignore_css_margins, - page_params.print_scaling_option == - blink::WebPrintScalingOptionFitToPrintableArea, - scale_factor); - CalculatePageLayoutFromPrintParams(params, page_layout_in_points); -} - -bool PrintWebViewHelper::InitPrintSettings(bool fit_to_paper_size) { - PrintMsg_PrintPages_Params settings; - Send(new PrintHostMsg_GetDefaultPrintSettings(routing_id(), - &settings.params)); - // Check if the printer returned any settings, if the settings is empty, we - // can safely assume there are no printer drivers configured. So we safely - // terminate. - bool result = true; - if (!PrintMsg_Print_Params_IsValid(settings.params)) - result = false; - - if (result && - (settings.params.dpi < kMinDpi || settings.params.document_cookie == 0)) { - // Invalid print page settings. - NOTREACHED(); - result = false; - } - - // Reset to default values. - ignore_css_margins_ = false; - settings.pages.clear(); - - settings.params.print_scaling_option = - blink::WebPrintScalingOptionSourceSize; - if (fit_to_paper_size) { - settings.params.print_scaling_option = - blink::WebPrintScalingOptionFitToPrintableArea; - } - - print_pages_params_.reset(new PrintMsg_PrintPages_Params(settings)); - return result; -} - -bool PrintWebViewHelper::CalculateNumberOfPages(blink::WebLocalFrame* frame, - const blink::WebNode& node, - int* number_of_pages) { - DCHECK(frame); - bool fit_to_paper_size = !(PrintingNodeOrPdfFrame(frame, node)); - if (!InitPrintSettings(fit_to_paper_size)) { - notify_browser_of_print_failure_ = false; -#if !defined(OS_ANDROID) - // TODO(sgurun) android_webview hack - render_view()->RunModalAlertDialog( - frame, - l10n_util::GetStringUTF16(IDS_PRINT_INVALID_PRINTER_SETTINGS)); -#endif // !defined(OS_ANDROID) - return false; - } - - const PrintMsg_Print_Params& params = print_pages_params_->params; - PrepareFrameAndViewForPrint prepare(params, frame, node, ignore_css_margins_); - prepare.StartPrinting(); - - Send(new PrintHostMsg_DidGetDocumentCookie(routing_id(), - params.document_cookie)); - *number_of_pages = prepare.GetExpectedPageCount(); - return true; -} - -bool PrintWebViewHelper::UpdatePrintSettings( - blink::WebLocalFrame* frame, - const blink::WebNode& node, - const base::DictionaryValue& passed_job_settings) { - DCHECK(is_preview_enabled_); - const base::DictionaryValue* job_settings = &passed_job_settings; - base::DictionaryValue modified_job_settings; - if (job_settings->empty()) { - if (!print_for_preview_) - print_preview_context_.set_error(PREVIEW_ERROR_BAD_SETTING); - return false; - } - - bool source_is_html = true; - if (print_for_preview_) { - if (!job_settings->GetBoolean(kSettingPreviewModifiable, &source_is_html)) { - NOTREACHED(); - } - } else { - source_is_html = !PrintingNodeOrPdfFrame(frame, node); - } - - if (print_for_preview_ || !source_is_html) { - modified_job_settings.MergeDictionary(job_settings); - modified_job_settings.SetBoolean(kSettingHeaderFooterEnabled, false); - modified_job_settings.SetInteger(kSettingMarginsType, NO_MARGINS); - job_settings = &modified_job_settings; - } - - // Send the cookie so that UpdatePrintSettings can reuse PrinterQuery when - // possible. - int cookie = print_pages_params_.get() ? - print_pages_params_->params.document_cookie : 0; - PrintMsg_PrintPages_Params settings; - Send(new PrintHostMsg_UpdatePrintSettings(routing_id(), cookie, *job_settings, - &settings)); - print_pages_params_.reset(new PrintMsg_PrintPages_Params(settings)); - - if (!PrintMsg_Print_Params_IsValid(settings.params)) { - if (!print_for_preview_) { - print_preview_context_.set_error(PREVIEW_ERROR_INVALID_PRINTER_SETTINGS); - } else { -#if !defined(OS_ANDROID) - // TODO(sgurun) android_webview hack - // PrintForPrintPreview - blink::WebFrame* print_frame = NULL; - // This may not be the right frame, but the alert will be modal, - // therefore it works well enough. - GetPrintFrame(&print_frame); - if (print_frame) { - render_view()->RunModalAlertDialog( - print_frame, - l10n_util::GetStringUTF16( - IDS_PRINT_INVALID_PRINTER_SETTINGS)); - } -#endif // !defined(OS_ANDROID) - } - return false; - } - - if (settings.params.dpi < kMinDpi || !settings.params.document_cookie) { - print_preview_context_.set_error(PREVIEW_ERROR_UPDATING_PRINT_SETTINGS); - return false; - } - - if (!job_settings->GetInteger(kPreviewUIID, &settings.params.preview_ui_id)) { - NOTREACHED(); - print_preview_context_.set_error(PREVIEW_ERROR_BAD_SETTING); - return false; - } - - if (!print_for_preview_) { - // Validate expected print preview settings. - if (!job_settings->GetInteger(kPreviewRequestID, - &settings.params.preview_request_id) || - !job_settings->GetBoolean(kIsFirstRequest, - &settings.params.is_first_request)) { - NOTREACHED(); - print_preview_context_.set_error(PREVIEW_ERROR_BAD_SETTING); - return false; - } - - settings.params.print_to_pdf = IsPrintToPdfRequested(*job_settings); - UpdateFrameMarginsCssInfo(*job_settings); - settings.params.print_scaling_option = GetPrintScalingOption( - source_is_html, *job_settings, settings.params); - - // Header/Footer: Set |header_footer_info_|. - if (settings.params.display_header_footer) { - header_footer_info_.reset(new base::DictionaryValue()); - header_footer_info_->SetDouble(kSettingHeaderFooterDate, - base::Time::Now().ToJsTime()); - header_footer_info_->SetString(kSettingHeaderFooterURL, - settings.params.url); - header_footer_info_->SetString(kSettingHeaderFooterTitle, - settings.params.title); - } - } - - print_pages_params_.reset(new PrintMsg_PrintPages_Params(settings)); - Send(new PrintHostMsg_DidGetDocumentCookie(routing_id(), - settings.params.document_cookie)); - - return true; -} - -bool PrintWebViewHelper::GetPrintSettingsFromUser(blink::WebFrame* frame, - const blink::WebNode& node, - int expected_pages_count) { - PrintHostMsg_ScriptedPrint_Params params; - PrintMsg_PrintPages_Params print_settings; - - params.cookie = print_pages_params_->params.document_cookie; - params.has_selection = frame->hasSelection(); - params.expected_pages_count = expected_pages_count; - MarginType margin_type = DEFAULT_MARGINS; - if (PrintingNodeOrPdfFrame(frame, node)) - margin_type = GetMarginsForPdf(frame, node); - params.margin_type = margin_type; - - Send(new PrintHostMsg_DidShowPrintDialog(routing_id())); - - // PrintHostMsg_ScriptedPrint will reset print_scaling_option, so we save the - // value before and restore it afterwards. - blink::WebPrintScalingOption scaling_option = - print_pages_params_->params.print_scaling_option; - - print_pages_params_.reset(); - IPC::SyncMessage* msg = - new PrintHostMsg_ScriptedPrint(routing_id(), params, &print_settings); - msg->EnableMessagePumping(); - Send(msg); - print_pages_params_.reset(new PrintMsg_PrintPages_Params(print_settings)); - - print_pages_params_->params.print_scaling_option = scaling_option; - return (print_settings.params.dpi && print_settings.params.document_cookie); -} - -bool PrintWebViewHelper::RenderPagesForPrint(blink::WebLocalFrame* frame, - const blink::WebNode& node) { - if (!frame || prep_frame_view_) - return false; - const PrintMsg_PrintPages_Params& params = *print_pages_params_; - const PrintMsg_Print_Params& print_params = params.params; - prep_frame_view_.reset(new PrepareFrameAndViewForPrint( - print_params, frame, node, ignore_css_margins_)); - DCHECK(!print_pages_params_->params.selection_only || - print_pages_params_->pages.empty()); - prep_frame_view_->CopySelectionIfNeeded( - render_view()->GetWebkitPreferences(), - base::Bind(&PrintWebViewHelper::OnFramePreparedForPrintPages, - base::Unretained(this))); - return true; -} - -#if defined(OS_POSIX) -bool PrintWebViewHelper::CopyMetafileDataToSharedMem( - PdfMetafileSkia* metafile, - base::SharedMemoryHandle* shared_mem_handle) { - uint32 buf_size = metafile->GetDataSize(); - scoped_ptr<base::SharedMemory> shared_buf( - content::RenderThread::Get()->HostAllocateSharedMemoryBuffer( - buf_size).release()); - - if (shared_buf.get()) { - if (shared_buf->Map(buf_size)) { - metafile->GetData(shared_buf->memory(), buf_size); - shared_buf->GiveToProcess(base::GetCurrentProcessHandle(), - shared_mem_handle); - return true; - } - } - NOTREACHED(); - return false; -} -#endif // defined(OS_POSIX) - -bool PrintWebViewHelper::IsScriptInitiatedPrintTooFrequent( - blink::WebFrame* frame) { - const int kMinSecondsToIgnoreJavascriptInitiatedPrint = 2; - const int kMaxSecondsToIgnoreJavascriptInitiatedPrint = 32; - bool too_frequent = false; - - // Check if there is script repeatedly trying to print and ignore it if too - // frequent. The first 3 times, we use a constant wait time, but if this - // gets excessive, we switch to exponential wait time. So for a page that - // calls print() in a loop the user will need to cancel the print dialog - // after: [2, 2, 2, 4, 8, 16, 32, 32, ...] seconds. - // This gives the user time to navigate from the page. - if (user_cancelled_scripted_print_count_ > 0) { - base::TimeDelta diff = base::Time::Now() - last_cancelled_script_print_; - int min_wait_seconds = kMinSecondsToIgnoreJavascriptInitiatedPrint; - if (user_cancelled_scripted_print_count_ > 3) { - min_wait_seconds = std::min( - kMinSecondsToIgnoreJavascriptInitiatedPrint << - (user_cancelled_scripted_print_count_ - 3), - kMaxSecondsToIgnoreJavascriptInitiatedPrint); - } - if (diff.InSeconds() < min_wait_seconds) { - too_frequent = true; - } - } - - if (!too_frequent) - return false; - - blink::WebString message( - blink::WebString::fromUTF8("Ignoring too frequent calls to print().")); - frame->addMessageToConsole( - blink::WebConsoleMessage( - blink::WebConsoleMessage::LevelWarning, message)); - return true; -} - -void PrintWebViewHelper::ResetScriptedPrintCount() { - // Reset cancel counter on successful print. - user_cancelled_scripted_print_count_ = 0; -} - -void PrintWebViewHelper::IncrementScriptedPrintCount() { - ++user_cancelled_scripted_print_count_; - last_cancelled_script_print_ = base::Time::Now(); -} - -void PrintWebViewHelper::ShowScriptedPrintPreview() { - if (is_scripted_preview_delayed_) { - is_scripted_preview_delayed_ = false; - Send(new PrintHostMsg_ShowScriptedPrintPreview(routing_id(), - print_preview_context_.IsModifiable())); - } -} - -void PrintWebViewHelper::RequestPrintPreview(PrintPreviewRequestType type) { - const bool is_modifiable = print_preview_context_.IsModifiable(); - const bool has_selection = print_preview_context_.HasSelection(); - PrintHostMsg_RequestPrintPreview_Params params; - params.is_modifiable = is_modifiable; - params.has_selection = has_selection; - switch (type) { - case PRINT_PREVIEW_SCRIPTED: { - // Shows scripted print preview in two stages. - // 1. PrintHostMsg_SetupScriptedPrintPreview blocks this call and JS by - // pumping messages here. - // 2. PrintHostMsg_ShowScriptedPrintPreview shows preview once the - // document has been loaded. - is_scripted_preview_delayed_ = true; - if (is_loading_ && GetPlugin(print_preview_context_.source_frame())) { - // Wait for DidStopLoading. Plugins may not know the correct - // |is_modifiable| value until they are fully loaded, which occurs when - // DidStopLoading() is called. Defer showing the preview until then. - } else { - base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&PrintWebViewHelper::ShowScriptedPrintPreview, - weak_ptr_factory_.GetWeakPtr())); - } - IPC::SyncMessage* msg = - new PrintHostMsg_SetupScriptedPrintPreview(routing_id()); - msg->EnableMessagePumping(); - Send(msg); - is_scripted_preview_delayed_ = false; - return; - } - case PRINT_PREVIEW_USER_INITIATED_ENTIRE_FRAME: { - break; - } - case PRINT_PREVIEW_USER_INITIATED_SELECTION: { - DCHECK(has_selection); - params.selection_only = has_selection; - break; - } - case PRINT_PREVIEW_USER_INITIATED_CONTEXT_NODE: { - params.webnode_only = true; - break; - } - default: { - NOTREACHED(); - return; - } - } - Send(new PrintHostMsg_RequestPrintPreview(routing_id(), params)); -} - -bool PrintWebViewHelper::CheckForCancel() { - const PrintMsg_Print_Params& print_params = print_pages_params_->params; - bool cancel = false; - Send(new PrintHostMsg_CheckForCancel(routing_id(), - print_params.preview_ui_id, - print_params.preview_request_id, - &cancel)); - if (cancel) - notify_browser_of_print_failure_ = false; - return cancel; -} - -bool PrintWebViewHelper::PreviewPageRendered(int page_number, - PdfMetafileSkia* metafile) { - DCHECK_GE(page_number, FIRST_PAGE_INDEX); - - // For non-modifiable files, |metafile| should be NULL, so do not bother - // sending a message. If we don't generate draft metafiles, |metafile| is - // NULL. - if (!print_preview_context_.IsModifiable() || - !print_preview_context_.generate_draft_pages()) { - DCHECK(!metafile); - return true; - } - - if (!metafile) { - NOTREACHED(); - print_preview_context_.set_error( - PREVIEW_ERROR_PAGE_RENDERED_WITHOUT_METAFILE); - return false; - } - - PrintHostMsg_DidPreviewPage_Params preview_page_params; - // Get the size of the resulting metafile. - uint32 buf_size = metafile->GetDataSize(); - DCHECK_GT(buf_size, 0u); - if (!CopyMetafileDataToSharedMem( - metafile, &(preview_page_params.metafile_data_handle))) { - LOG(ERROR) << "CopyMetafileDataToSharedMem failed"; - print_preview_context_.set_error(PREVIEW_ERROR_METAFILE_COPY_FAILED); - return false; - } - preview_page_params.data_size = buf_size; - preview_page_params.page_number = page_number; - preview_page_params.preview_request_id = - print_pages_params_->params.preview_request_id; - - Send(new PrintHostMsg_DidPreviewPage(routing_id(), preview_page_params)); - return true; -} - -PrintWebViewHelper::PrintPreviewContext::PrintPreviewContext() - : total_page_count_(0), - current_page_index_(0), - generate_draft_pages_(true), - print_ready_metafile_page_count_(0), - error_(PREVIEW_ERROR_NONE), - state_(UNINITIALIZED) { -} - -PrintWebViewHelper::PrintPreviewContext::~PrintPreviewContext() { -} - -void PrintWebViewHelper::PrintPreviewContext::InitWithFrame( - blink::WebLocalFrame* web_frame) { - DCHECK(web_frame); - DCHECK(!IsRendering()); - state_ = INITIALIZED; - source_frame_.Reset(web_frame); - source_node_.reset(); -} - -void PrintWebViewHelper::PrintPreviewContext::InitWithNode( - const blink::WebNode& web_node) { - DCHECK(!web_node.isNull()); - DCHECK(web_node.document().frame()); - DCHECK(!IsRendering()); - state_ = INITIALIZED; - source_frame_.Reset(web_node.document().frame()); - source_node_ = web_node; -} - -void PrintWebViewHelper::PrintPreviewContext::OnPrintPreview() { - DCHECK_EQ(INITIALIZED, state_); - ClearContext(); -} - -bool PrintWebViewHelper::PrintPreviewContext::CreatePreviewDocument( - PrepareFrameAndViewForPrint* prepared_frame, - const std::vector<int>& pages) { - DCHECK_EQ(INITIALIZED, state_); - state_ = RENDERING; - - // Need to make sure old object gets destroyed first. - prep_frame_view_.reset(prepared_frame); - prep_frame_view_->StartPrinting(); - - total_page_count_ = prep_frame_view_->GetExpectedPageCount(); - if (total_page_count_ == 0) { - LOG(ERROR) << "CreatePreviewDocument got 0 page count"; - set_error(PREVIEW_ERROR_ZERO_PAGES); - return false; - } - - metafile_.reset(new PdfMetafileSkia); - if (!metafile_->Init()) { - set_error(PREVIEW_ERROR_METAFILE_INIT_FAILED); - LOG(ERROR) << "PdfMetafileSkia Init failed"; - return false; - } - - current_page_index_ = 0; - pages_to_render_ = pages; - // Sort and make unique. - std::sort(pages_to_render_.begin(), pages_to_render_.end()); - pages_to_render_.resize(std::unique(pages_to_render_.begin(), - pages_to_render_.end()) - - pages_to_render_.begin()); - // Remove invalid pages. - pages_to_render_.resize(std::lower_bound(pages_to_render_.begin(), - pages_to_render_.end(), - total_page_count_) - - pages_to_render_.begin()); - print_ready_metafile_page_count_ = pages_to_render_.size(); - if (pages_to_render_.empty()) { - print_ready_metafile_page_count_ = total_page_count_; - // Render all pages. - for (int i = 0; i < total_page_count_; ++i) - pages_to_render_.push_back(i); - } else if (generate_draft_pages_) { - int pages_index = 0; - for (int i = 0; i < total_page_count_; ++i) { - if (pages_index < print_ready_metafile_page_count_ && - i == pages_to_render_[pages_index]) { - pages_index++; - continue; - } - pages_to_render_.push_back(i); - } - } - - document_render_time_ = base::TimeDelta(); - begin_time_ = base::TimeTicks::Now(); - - return true; -} - -void PrintWebViewHelper::PrintPreviewContext::RenderedPreviewPage( - const base::TimeDelta& page_time) { - DCHECK_EQ(RENDERING, state_); - document_render_time_ += page_time; - UMA_HISTOGRAM_TIMES("PrintPreview.RenderPDFPageTime", page_time); -} - -void PrintWebViewHelper::PrintPreviewContext::AllPagesRendered() { - DCHECK_EQ(RENDERING, state_); - state_ = DONE; - prep_frame_view_->FinishPrinting(); -} - -void PrintWebViewHelper::PrintPreviewContext::FinalizePrintReadyDocument() { - DCHECK(IsRendering()); - - base::TimeTicks begin_time = base::TimeTicks::Now(); - metafile_->FinishDocument(); - - if (print_ready_metafile_page_count_ <= 0) { - NOTREACHED(); - return; - } - - UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderToPDFTime", - document_render_time_); - base::TimeDelta total_time = (base::TimeTicks::Now() - begin_time) + - document_render_time_; - UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderAndGeneratePDFTime", - total_time); - UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderAndGeneratePDFTimeAvgPerPage", - total_time / pages_to_render_.size()); -} - -void PrintWebViewHelper::PrintPreviewContext::Finished() { - DCHECK_EQ(DONE, state_); - state_ = INITIALIZED; - ClearContext(); -} - -void PrintWebViewHelper::PrintPreviewContext::Failed(bool report_error) { - DCHECK(state_ == INITIALIZED || state_ == RENDERING); - state_ = INITIALIZED; - if (report_error) { - DCHECK_NE(PREVIEW_ERROR_NONE, error_); - UMA_HISTOGRAM_ENUMERATION("PrintPreview.RendererError", error_, - PREVIEW_ERROR_LAST_ENUM); - } - ClearContext(); -} - -int PrintWebViewHelper::PrintPreviewContext::GetNextPageNumber() { - DCHECK_EQ(RENDERING, state_); - if (IsFinalPageRendered()) - return -1; - return pages_to_render_[current_page_index_++]; -} - -bool PrintWebViewHelper::PrintPreviewContext::IsRendering() const { - return state_ == RENDERING || state_ == DONE; -} - -bool PrintWebViewHelper::PrintPreviewContext::IsModifiable() { - // The only kind of node we can print right now is a PDF node. - return !PrintingNodeOrPdfFrame(source_frame(), source_node_); -} - -bool PrintWebViewHelper::PrintPreviewContext::HasSelection() { - return IsModifiable() && source_frame()->hasSelection(); -} - -bool PrintWebViewHelper::PrintPreviewContext::IsLastPageOfPrintReadyMetafile() - const { - DCHECK(IsRendering()); - return current_page_index_ == print_ready_metafile_page_count_; -} - -bool PrintWebViewHelper::PrintPreviewContext::IsFinalPageRendered() const { - DCHECK(IsRendering()); - return static_cast<size_t>(current_page_index_) == pages_to_render_.size(); -} - -void PrintWebViewHelper::PrintPreviewContext::set_generate_draft_pages( - bool generate_draft_pages) { - DCHECK_EQ(INITIALIZED, state_); - generate_draft_pages_ = generate_draft_pages; -} - -void PrintWebViewHelper::PrintPreviewContext::set_error( - enum PrintPreviewErrorBuckets error) { - error_ = error; -} - -blink::WebLocalFrame* PrintWebViewHelper::PrintPreviewContext::source_frame() { - DCHECK_NE(UNINITIALIZED, state_); - return source_frame_.GetFrame(); -} - -const blink::WebNode& - PrintWebViewHelper::PrintPreviewContext::source_node() const { - DCHECK_NE(UNINITIALIZED, state_); - return source_node_; -} - -blink::WebLocalFrame* -PrintWebViewHelper::PrintPreviewContext::prepared_frame() { - DCHECK_NE(UNINITIALIZED, state_); - return prep_frame_view_->frame(); -} - -const blink::WebNode& - PrintWebViewHelper::PrintPreviewContext::prepared_node() const { - DCHECK_NE(UNINITIALIZED, state_); - return prep_frame_view_->node(); -} - -int PrintWebViewHelper::PrintPreviewContext::total_page_count() const { - DCHECK_NE(UNINITIALIZED, state_); - return total_page_count_; -} - -bool PrintWebViewHelper::PrintPreviewContext::generate_draft_pages() const { - return generate_draft_pages_; -} - -PdfMetafileSkia* PrintWebViewHelper::PrintPreviewContext::metafile() { - DCHECK(IsRendering()); - return metafile_.get(); -} - -int PrintWebViewHelper::PrintPreviewContext::last_error() const { - return error_; -} - -gfx::Size PrintWebViewHelper::PrintPreviewContext::GetPrintCanvasSize() const { - DCHECK(IsRendering()); - return prep_frame_view_->GetPrintCanvasSize(); -} - -void PrintWebViewHelper::PrintPreviewContext::ClearContext() { - prep_frame_view_.reset(); - metafile_.reset(); - pages_to_render_.clear(); - error_ = PREVIEW_ERROR_NONE; -} - -} // namespace printing diff --git a/android_webview/renderer/print_web_view_helper.h b/android_webview/renderer/print_web_view_helper.h deleted file mode 100644 index 529a67f..0000000 --- a/android_webview/renderer/print_web_view_helper.h +++ /dev/null @@ -1,478 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// TODO(sgurun) copied from chrome/renderer. Remove after crbug.com/322276 - -#ifndef AW_RENDERER_PRINT_WEB_VIEW_HELPER_H_ -#define AW_RENDERER_PRINT_WEB_VIEW_HELPER_H_ - -#include <vector> - -#include "base/gtest_prod_util.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/shared_memory.h" -#include "base/memory/weak_ptr.h" -#include "base/time/time.h" -#include "content/public/renderer/render_view_observer.h" -#include "content/public/renderer/render_view_observer_tracker.h" -#include "printing/pdf_metafile_skia.h" -#include "third_party/WebKit/public/platform/WebCanvas.h" -#include "third_party/WebKit/public/web/WebNode.h" -#include "third_party/WebKit/public/web/WebPrintParams.h" -#include "ui/gfx/geometry/size.h" - -struct PrintMsg_Print_Params; -struct PrintMsg_PrintPage_Params; -struct PrintMsg_PrintPages_Params; - -namespace base { -class DictionaryValue; -} - -namespace blink { -class WebFrame; -class WebView; -} - -namespace printing { - -struct PageSizeMargins; -class PrepareFrameAndViewForPrint; - -// Stores reference to frame using WebVew and unique name. -// Workaround to modal dialog issue on Linux. crbug.com/236147. -// If WebFrame someday supports WeakPtr, we should use it here. -class FrameReference { - public: - explicit FrameReference(blink::WebLocalFrame* frame); - FrameReference(); - ~FrameReference(); - - void Reset(blink::WebLocalFrame* frame); - - blink::WebLocalFrame* GetFrame(); - blink::WebView* view(); - - private: - blink::WebView* view_; - blink::WebLocalFrame* frame_; -}; - -// PrintWebViewHelper handles most of the printing grunt work for RenderView. -// We plan on making print asynchronous and that will require copying the DOM -// of the document and creating a new WebView with the contents. -class PrintWebViewHelper - : public content::RenderViewObserver, - public content::RenderViewObserverTracker<PrintWebViewHelper> { - public: - explicit PrintWebViewHelper(content::RenderView* render_view); - virtual ~PrintWebViewHelper(); - - bool IsPrintingEnabled(); - - void PrintNode(const blink::WebNode& node); - - private: - friend class PrintWebViewHelperTestBase; - FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest, - BlockScriptInitiatedPrinting); - FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest, - BlockScriptInitiatedPrintingFromPopup); - FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest, OnPrintPages); - -#if defined(OS_WIN) || defined(OS_MACOSX) - FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest, PrintLayoutTest); - FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest, PrintWithIframe); -#endif // defined(OS_WIN) || defined(OS_MACOSX) - - enum PrintingResult { - OK, - FAIL_PRINT_INIT, - FAIL_PRINT, - FAIL_PREVIEW, - }; - - enum PrintPreviewErrorBuckets { - PREVIEW_ERROR_NONE, // Always first. - PREVIEW_ERROR_BAD_SETTING, - PREVIEW_ERROR_METAFILE_COPY_FAILED, - PREVIEW_ERROR_METAFILE_INIT_FAILED, - PREVIEW_ERROR_ZERO_PAGES, - PREVIEW_ERROR_MAC_DRAFT_METAFILE_INIT_FAILED, - PREVIEW_ERROR_PAGE_RENDERED_WITHOUT_METAFILE, - PREVIEW_ERROR_UPDATING_PRINT_SETTINGS, - PREVIEW_ERROR_INVALID_PRINTER_SETTINGS, - PREVIEW_ERROR_LAST_ENUM // Always last. - }; - - enum PrintPreviewRequestType { - PRINT_PREVIEW_USER_INITIATED_ENTIRE_FRAME, - PRINT_PREVIEW_USER_INITIATED_SELECTION, - PRINT_PREVIEW_USER_INITIATED_CONTEXT_NODE, - PRINT_PREVIEW_SCRIPTED // triggered by window.print(). - }; - - // RenderViewObserver implementation. - virtual bool OnMessageReceived(const IPC::Message& message) override; - virtual void PrintPage(blink::WebLocalFrame* frame, - bool user_initiated) override; - virtual void DidStartLoading() override; - virtual void DidStopLoading() override; - - // Message handlers --------------------------------------------------------- - void OnPrintPages(); - void OnPrintForSystemDialog(); - void OnInitiatePrintPreview(bool selection_only); - void OnPrintPreview(const base::DictionaryValue& settings); - void OnPrintForPrintPreview(const base::DictionaryValue& job_settings); - void OnPrintingDone(bool success); - - // Get |page_size| and |content_area| information from - // |page_layout_in_points|. - void GetPageSizeAndContentAreaFromPageLayout( - const PageSizeMargins& page_layout_in_points, - gfx::Size* page_size, - gfx::Rect* content_area); - - // Update |ignore_css_margins_| based on settings. - void UpdateFrameMarginsCssInfo(const base::DictionaryValue& settings); - - // Returns true if the current destination printer is PRINT_TO_PDF. - bool IsPrintToPdfRequested(const base::DictionaryValue& settings); - - // Returns the print scaling option to retain/scale/crop the source page size - // to fit the printable area of the paper. - // - // We retain the source page size when the current destination printer is - // SAVE_AS_PDF. - // - // We crop the source page size to fit the printable area or we print only the - // left top page contents when - // (1) Source is PDF and the user has requested not to fit to printable area - // via |job_settings|. - // (2) Source is PDF. This is the first preview request and print scaling - // option is disabled for initiator renderer plugin. - // - // In all other cases, we scale the source page to fit the printable area. - blink::WebPrintScalingOption GetPrintScalingOption( - bool source_is_html, - const base::DictionaryValue& job_settings, - const PrintMsg_Print_Params& params); - - // Prepare frame for creating preview document. - void PrepareFrameForPreviewDocument(); - - // Continue creating preview document. - void OnFramePreparedForPreviewDocument(); - - // Initialize the print preview document. - bool CreatePreviewDocument(); - - // Renders a print preview page. |page_number| is 0-based. - // Returns true if print preview should continue, false on failure. - bool RenderPreviewPage(int page_number, - const PrintMsg_Print_Params& print_params); - - // Finalize the print ready preview document. - bool FinalizePrintReadyDocument(); - - // Enable/Disable window.print calls. If |blocked| is true window.print - // calls will silently fail. Call with |blocked| set to false to reenable. - void SetScriptedPrintBlocked(bool blocked); - - // Main printing code ------------------------------------------------------- - - void Print(blink::WebLocalFrame* frame, const blink::WebNode& node); - - // Notification when printing is done - signal tear-down/free resources. - void DidFinishPrinting(PrintingResult result); - - // Print Settings ----------------------------------------------------------- - - // Initialize print page settings with default settings. - // Used only for native printing workflow. - bool InitPrintSettings(bool fit_to_paper_size); - - // Calculate number of pages in source document. - bool CalculateNumberOfPages(blink::WebLocalFrame* frame, - const blink::WebNode& node, - int* number_of_pages); - - // Update the current print settings with new |passed_job_settings|. - // |passed_job_settings| dictionary contains print job details such as printer - // name, number of copies, page range, etc. - bool UpdatePrintSettings(blink::WebLocalFrame* frame, - const blink::WebNode& node, - const base::DictionaryValue& passed_job_settings); - - // Get final print settings from the user. - // Return false if the user cancels or on error. - bool GetPrintSettingsFromUser(blink::WebFrame* frame, - const blink::WebNode& node, - int expected_pages_count); - - // Page Printing / Rendering ------------------------------------------------ - - void OnFramePreparedForPrintPages(); - void PrintPages(); - bool PrintPagesNative(blink::WebFrame* frame, - int page_count, - const gfx::Size& canvas_size); - void FinishFramePrinting(); - - // Prints the page listed in |params|. -#if defined(OS_LINUX) || defined(OS_ANDROID) - void PrintPageInternal(const PrintMsg_PrintPage_Params& params, - const gfx::Size& canvas_size, - blink::WebFrame* frame, - PdfMetafileSkia* metafile); -#else - void PrintPageInternal(const PrintMsg_PrintPage_Params& params, - const gfx::Size& canvas_size, - blink::WebFrame* frame); -#endif - - // Render the frame for printing. - bool RenderPagesForPrint(blink::WebLocalFrame* frame, - const blink::WebNode& node); - - // Platform specific helper function for rendering page(s) to |metafile|. -#if defined(OS_WIN) - void RenderPage(const PrintMsg_Print_Params& params, - int page_number, - blink::WebFrame* frame, - bool is_preview, - PdfMetafileSkia* metafile, - double* scale_factor, - gfx::Size* page_size_in_dpi, - gfx::Rect* content_area_in_dpi); -#elif defined(OS_MACOSX) - void RenderPage(const PrintMsg_Print_Params& params, - int page_number, - blink::WebFrame* frame, - bool is_preview, - PdfMetafileSkia* metafile, - gfx::Size* page_size, - gfx::Rect* content_rect); -#endif // defined(OS_WIN) - - // Renders page contents from |frame| to |content_area| of |canvas|. - // |page_number| is zero-based. - // When method is called, canvas should be setup to draw to |canvas_area| - // with |scale_factor|. - static float RenderPageContent(blink::WebFrame* frame, - int page_number, - const gfx::Rect& canvas_area, - const gfx::Rect& content_area, - double scale_factor, - blink::WebCanvas* canvas); - - // Helper methods ----------------------------------------------------------- - - bool CopyMetafileDataToSharedMem(PdfMetafileSkia* metafile, - base::SharedMemoryHandle* shared_mem_handle); - - // Helper method to get page layout in points and fit to page if needed. - static void ComputePageLayoutInPointsForCss( - blink::WebFrame* frame, - int page_index, - const PrintMsg_Print_Params& default_params, - bool ignore_css_margins, - double* scale_factor, - PageSizeMargins* page_layout_in_points); - - // Given the |device| and |canvas| to draw on, prints the appropriate headers - // and footers using strings from |header_footer_info| on to the canvas. - static void PrintHeaderAndFooter( - blink::WebCanvas* canvas, - int page_number, - int total_pages, - float webkit_scale_factor, - const PageSizeMargins& page_layout_in_points, - const base::DictionaryValue& header_footer_info, - const PrintMsg_Print_Params& params); - - bool GetPrintFrame(blink::WebLocalFrame** frame); - - // Script Initiated Printing ------------------------------------------------ - - // Return true if script initiated printing is currently - // allowed. |user_initiated| should be true when a user event triggered the - // script, most likely by pressing a print button on the page. - bool IsScriptInitiatedPrintAllowed(blink::WebFrame* frame, - bool user_initiated); - - // Returns true if script initiated printing occurs too often. - bool IsScriptInitiatedPrintTooFrequent(blink::WebFrame* frame); - - // Reset the counter for script initiated printing. - // Scripted printing will be allowed to continue. - void ResetScriptedPrintCount(); - - // Increment the counter for script initiated printing. - // Scripted printing will be blocked for a limited amount of time. - void IncrementScriptedPrintCount(); - - // Shows scripted print preview when options from plugin are availible. - void ShowScriptedPrintPreview(); - - void RequestPrintPreview(PrintPreviewRequestType type); - - // Checks whether print preview should continue or not. - // Returns true if cancelling, false if continuing. - bool CheckForCancel(); - - // Notifies the browser a print preview page has been rendered. - // |page_number| is 0-based. - // For a valid |page_number| with modifiable content, - // |metafile| is the rendered page. Otherwise |metafile| is NULL. - // Returns true if print preview should continue, false on failure. - bool PreviewPageRendered(int page_number, PdfMetafileSkia* metafile); - - // WebView used only to print the selection. - scoped_ptr<PrepareFrameAndViewForPrint> prep_frame_view_; - bool reset_prep_frame_view_; - - scoped_ptr<PrintMsg_PrintPages_Params> print_pages_params_; - bool is_preview_enabled_; - bool is_scripted_print_throttling_disabled_; - bool is_print_ready_metafile_sent_; - bool ignore_css_margins_; - - // Used for scripted initiated printing blocking. - base::Time last_cancelled_script_print_; - int user_cancelled_scripted_print_count_; - bool is_scripted_printing_blocked_; - - // Let the browser process know of a printing failure. Only set to false when - // the failure came from the browser in the first place. - bool notify_browser_of_print_failure_; - - // True, when printing from print preview. - bool print_for_preview_; - - // Strings generated by the browser process to be printed as headers and - // footers if requested by the user. - scoped_ptr<base::DictionaryValue> header_footer_info_; - - // Keeps track of the state of print preview between messages. - // TODO(vitalybuka): Create PrintPreviewContext when needed and delete after - // use. Now it's interaction with various messages is confusing. - class PrintPreviewContext { - public: - PrintPreviewContext(); - ~PrintPreviewContext(); - - // Initializes the print preview context. Need to be called to set - // the |web_frame| / |web_node| to generate the print preview for. - void InitWithFrame(blink::WebLocalFrame* web_frame); - void InitWithNode(const blink::WebNode& web_node); - - // Does bookkeeping at the beginning of print preview. - void OnPrintPreview(); - - // Create the print preview document. |pages| is empty to print all pages. - // Takes ownership of |prepared_frame|. - bool CreatePreviewDocument(PrepareFrameAndViewForPrint* prepared_frame, - const std::vector<int>& pages); - - // Called after a page gets rendered. |page_time| is how long the - // rendering took. - void RenderedPreviewPage(const base::TimeDelta& page_time); - - // Updates the print preview context when the required pages are rendered. - void AllPagesRendered(); - - // Finalizes the print ready preview document. - void FinalizePrintReadyDocument(); - - // Cleanup after print preview finishes. - void Finished(); - - // Cleanup after print preview fails. - void Failed(bool report_error); - - // Helper functions - int GetNextPageNumber(); - bool IsRendering() const; - bool IsModifiable(); - bool HasSelection(); - bool IsLastPageOfPrintReadyMetafile() const; - bool IsFinalPageRendered() const; - - // Setters - void set_generate_draft_pages(bool generate_draft_pages); - void set_error(enum PrintPreviewErrorBuckets error); - - // Getters - // Original frame for which preview was requested. - blink::WebLocalFrame* source_frame(); - // Original node for which preview was requested. - const blink::WebNode& source_node() const; - - // Frame to be use to render preview. May be the same as source_frame(), or - // generated from it, e.g. copy of selected block. - blink::WebLocalFrame* prepared_frame(); - // Node to be use to render preview. May be the same as source_node(), or - // generated from it, e.g. copy of selected block. - const blink::WebNode& prepared_node() const; - - int total_page_count() const; - bool generate_draft_pages() const; - PdfMetafileSkia* metafile(); - gfx::Size GetPrintCanvasSize() const; - int last_error() const; - - private: - enum State { - UNINITIALIZED, // Not ready to render. - INITIALIZED, // Ready to render. - RENDERING, // Rendering. - DONE // Finished rendering. - }; - - // Reset some of the internal rendering context. - void ClearContext(); - - // Specifies what to render for print preview. - FrameReference source_frame_; - blink::WebNode source_node_; - - scoped_ptr<PrepareFrameAndViewForPrint> prep_frame_view_; - scoped_ptr<PdfMetafileSkia> metafile_; - - // Total page count in the renderer. - int total_page_count_; - - // The current page to render. - int current_page_index_; - - // List of page indices that need to be rendered. - std::vector<int> pages_to_render_; - - // True, when draft pages needs to be generated. - bool generate_draft_pages_; - - // Specifies the total number of pages in the print ready metafile. - int print_ready_metafile_page_count_; - - base::TimeDelta document_render_time_; - base::TimeTicks begin_time_; - - enum PrintPreviewErrorBuckets error_; - - State state_; - }; - - bool print_node_in_progress_; - PrintPreviewContext print_preview_context_; - bool is_loading_; - bool is_scripted_preview_delayed_; - base::WeakPtrFactory<PrintWebViewHelper> weak_ptr_factory_; - DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelper); -}; - -} // namespace printing - -#endif // AW_RENDERER_PRINT_WEB_VIEW_HELPER_H_ diff --git a/android_webview/renderer/print_web_view_helper_android.cc b/android_webview/renderer/print_web_view_helper_android.cc deleted file mode 100644 index d5eeaa7..0000000 --- a/android_webview/renderer/print_web_view_helper_android.cc +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// All the necessary logic already lives in print_web_view_helper_linux.cc. -// We need a separate file for Android due to build/filename_rules.gypi rules. - -// TODO(sgurun) copied from chrome/renderer. Remove after crbug.com/322276 - -#include "android_webview/renderer/print_web_view_helper_linux.cc" diff --git a/android_webview/renderer/print_web_view_helper_linux.cc b/android_webview/renderer/print_web_view_helper_linux.cc deleted file mode 100644 index 753c98b..0000000 --- a/android_webview/renderer/print_web_view_helper_linux.cc +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// TODO(sgurun) copied from chrome/renderer. Remove after crbug.com/322276 - -#include "android_webview/renderer/print_web_view_helper.h" - -#include "android_webview/common/print_messages.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "content/public/renderer/render_thread.h" -#include "printing/metafile_skia_wrapper.h" -#include "printing/page_size_margins.h" -#include "printing/pdf_metafile_skia.h" -#include "skia/ext/platform_device.h" -#include "skia/ext/vector_canvas.h" -#include "third_party/WebKit/public/web/WebLocalFrame.h" - -#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) -#include "base/process/process_handle.h" -#else -#include "base/file_descriptor_posix.h" -#endif // !defined(OS_CHROMEOS) && !defined(OS_ANDROID) - -namespace printing { - -using blink::WebFrame; - -bool PrintWebViewHelper::RenderPreviewPage( - int page_number, - const PrintMsg_Print_Params& print_params) { - PrintMsg_PrintPage_Params page_params; - page_params.params = print_params; - page_params.page_number = page_number; - scoped_ptr<PdfMetafileSkia> draft_metafile; - PdfMetafileSkia* initial_render_metafile = print_preview_context_.metafile(); - if (print_preview_context_.IsModifiable() && is_print_ready_metafile_sent_) { - draft_metafile.reset(new PdfMetafileSkia); - initial_render_metafile = draft_metafile.get(); - } - - base::TimeTicks begin_time = base::TimeTicks::Now(); - PrintPageInternal(page_params, - print_preview_context_.GetPrintCanvasSize(), - print_preview_context_.prepared_frame(), - initial_render_metafile); - print_preview_context_.RenderedPreviewPage( - base::TimeTicks::Now() - begin_time); - if (draft_metafile.get()) { - draft_metafile->FinishDocument(); - } else if (print_preview_context_.IsModifiable() && - print_preview_context_.generate_draft_pages()) { - DCHECK(!draft_metafile.get()); - draft_metafile = - print_preview_context_.metafile()->GetMetafileForCurrentPage(); - } - return PreviewPageRendered(page_number, draft_metafile.get()); -} - -bool PrintWebViewHelper::PrintPagesNative(blink::WebFrame* frame, - int page_count, - const gfx::Size& canvas_size) { - PdfMetafileSkia metafile; - if (!metafile.Init()) - return false; - - const PrintMsg_PrintPages_Params& params = *print_pages_params_; - std::vector<int> printed_pages; - - if (params.pages.empty()) { - for (int i = 0; i < page_count; ++i) { - printed_pages.push_back(i); - } - } else { - // TODO(vitalybuka): redesign to make more code cross platform. - for (size_t i = 0; i < params.pages.size(); ++i) { - if (params.pages[i] >= 0 && params.pages[i] < page_count) { - printed_pages.push_back(params.pages[i]); - } - } - } - - if (printed_pages.empty()) - return false; - - PrintMsg_PrintPage_Params page_params; - page_params.params = params.params; - for (size_t i = 0; i < printed_pages.size(); ++i) { - page_params.page_number = printed_pages[i]; - PrintPageInternal(page_params, canvas_size, frame, &metafile); - } - - // blink::printEnd() for PDF should be called before metafile is closed. - FinishFramePrinting(); - - metafile.FinishDocument(); - - // Get the size of the resulting metafile. - uint32 buf_size = metafile.GetDataSize(); - DCHECK_GT(buf_size, 0u); - -#if defined(OS_CHROMEOS) || defined(OS_ANDROID) - int sequence_number = -1; - base::FileDescriptor fd; - - // Ask the browser to open a file for us. - Send(new PrintHostMsg_AllocateTempFileForPrinting(routing_id(), - &fd, - &sequence_number)); - if (!metafile.SaveToFD(fd)) - return false; - - // Tell the browser we've finished writing the file. - Send(new PrintHostMsg_TempFileForPrintingWritten(routing_id(), - sequence_number)); - return true; -#else - PrintHostMsg_DidPrintPage_Params printed_page_params; - printed_page_params.data_size = 0; - printed_page_params.document_cookie = params.params.document_cookie; - - { - scoped_ptr<base::SharedMemory> shared_mem( - content::RenderThread::Get()->HostAllocateSharedMemoryBuffer( - buf_size).release()); - if (!shared_mem.get()) { - NOTREACHED() << "AllocateSharedMemoryBuffer failed"; - return false; - } - - if (!shared_mem->Map(buf_size)) { - NOTREACHED() << "Map failed"; - return false; - } - metafile.GetData(shared_mem->memory(), buf_size); - printed_page_params.data_size = buf_size; - shared_mem->GiveToProcess(base::GetCurrentProcessHandle(), - &(printed_page_params.metafile_data_handle)); - } - - for (size_t i = 0; i < printed_pages.size(); ++i) { - printed_page_params.page_number = printed_pages[i]; - Send(new PrintHostMsg_DidPrintPage(routing_id(), printed_page_params)); - // Send the rest of the pages with an invalid metafile handle. - printed_page_params.metafile_data_handle.fd = -1; - } - return true; -#endif // defined(OS_CHROMEOS) || defined(OS_ANDROID) -} - -void PrintWebViewHelper::PrintPageInternal( - const PrintMsg_PrintPage_Params& params, - const gfx::Size& canvas_size, - WebFrame* frame, - PdfMetafileSkia* metafile) { - PageSizeMargins page_layout_in_points; - double scale_factor = 1.0f; - ComputePageLayoutInPointsForCss(frame, params.page_number, params.params, - ignore_css_margins_, &scale_factor, - &page_layout_in_points); - gfx::Size page_size; - gfx::Rect content_area; - GetPageSizeAndContentAreaFromPageLayout(page_layout_in_points, &page_size, - &content_area); - gfx::Rect canvas_area = - params.params.display_header_footer ? gfx::Rect(page_size) : content_area; - - skia::VectorCanvas* canvas = - metafile->GetVectorCanvasForNewPage(page_size, canvas_area, scale_factor); - if (!canvas) - return; - - MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile); - skia::SetIsDraftMode(*canvas, is_print_ready_metafile_sent_); - - if (params.params.display_header_footer) { - // |page_number| is 0-based, so 1 is added. - // TODO(vitalybuka) : why does it work only with 1.25? - PrintHeaderAndFooter(canvas, params.page_number + 1, - print_preview_context_.total_page_count(), - scale_factor / 1.25, page_layout_in_points, - *header_footer_info_, params.params); - } - RenderPageContent(frame, params.page_number, canvas_area, content_area, - scale_factor, canvas); - - // Done printing. Close the canvas to retrieve the compiled metafile. - if (!metafile->FinishPage()) - NOTREACHED() << "metafile failed"; -} - -} // namespace printing diff --git a/components/components.gyp b/components/components.gyp index 1eb533c..e5714dd 100644 --- a/components/components.gyp +++ b/components/components.gyp @@ -140,10 +140,8 @@ 'webdata_services.gypi', ], }], - ['android_webview_build == 0 and OS != "ios"', { + ['enable_basic_printing==1 or enable_print_preview==1', { 'includes': [ - # TODO(dgn) move it to a condition based on whether print is enabled - # once the duplicates have been removed from webview. 'printing.gypi', ], }], diff --git a/components/printing/renderer/print_web_view_helper.cc b/components/printing/renderer/print_web_view_helper.cc index 72d801b..4c1c058 100644 --- a/components/printing/renderer/print_web_view_helper.cc +++ b/components/printing/renderer/print_web_view_helper.cc @@ -756,6 +756,14 @@ void PrepareFrameAndViewForPrint::FinishPrinting() { on_ready_.Reset(); } +bool PrintWebViewHelper::Delegate::IsAskPrintSettingsEnabled() { + return true; +} + +bool PrintWebViewHelper::Delegate::IsScriptedPrintEnabled() { + return true; +} + PrintWebViewHelper::PrintWebViewHelper( content::RenderView* render_view, scoped_ptr<Delegate> delegate) @@ -785,6 +793,9 @@ void PrintWebViewHelper::DisablePreview() { bool PrintWebViewHelper::IsScriptInitiatedPrintAllowed( blink::WebFrame* frame, bool user_initiated) { + if (!delegate_->IsScriptedPrintEnabled()) + return false; + // If preview is enabled, then the print dialog is tab modal, and the user // can always close the tab on a mis-behaving page (the system print dialog // is app modal). If the print was initiated through user action, don't @@ -1259,7 +1270,8 @@ void PrintWebViewHelper::Print(blink::WebLocalFrame* frame, } // Ask the browser to show UI to retrieve the final print settings. - if (!GetPrintSettingsFromUser(frame_ref.GetFrame(), node, + if (delegate_->IsAskPrintSettingsEnabled() && + !GetPrintSettingsFromUser(frame_ref.GetFrame(), node, expected_page_count, is_scripted)) { DidFinishPrinting(OK); // Release resources and fail silently. diff --git a/components/printing/renderer/print_web_view_helper.h b/components/printing/renderer/print_web_view_helper.h index 273b709..885f80a 100644 --- a/components/printing/renderer/print_web_view_helper.h +++ b/components/printing/renderer/print_web_view_helper.h @@ -85,6 +85,14 @@ class PrintWebViewHelper virtual bool IsPrintPreviewEnabled() = 0; + // If true, the user can be asked to provide print settings. + // The default implementation returns |true|. + virtual bool IsAskPrintSettingsEnabled(); + + // If false, window.print() won't do anything. + // The default implementation returns |true|. + virtual bool IsScriptedPrintEnabled(); + // Returns true if printing is overridden and the default behavior should be // skipped for |frame|. virtual bool OverridePrint(blink::WebLocalFrame* frame) = 0; |