Strip out print preview.

This commit is contained in:
Cheng Zhao 2014-08-21 22:14:27 +08:00
parent eb3ecab6a8
commit 99a510701d
9 changed files with 6 additions and 1513 deletions

View file

@ -18,26 +18,6 @@
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#if defined(ENABLE_FULL_PRINTING)
#include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
#endif
#if defined(OS_CHROMEOS)
#include <fcntl.h>
#include <map>
#include "base/file_util.h"
#include "base/lazy_instance.h"
#include "chrome/browser/printing/print_dialog_cloud.h"
#endif
#if defined(OS_ANDROID)
#include "base/strings/string_number_conversions.h"
#include "chrome/browser/printing/print_view_manager_basic.h"
#include "printing/printing_context_android.h"
#endif
using content::BrowserThread;
namespace {
@ -80,7 +60,6 @@ void RenderParamsFromPrintSettings(const printing::PrintSettings& settings,
params->selection_only = settings.selection_only();
params->supports_alpha_blend = settings.supports_alpha_blend();
params->should_print_backgrounds = settings.should_print_backgrounds();
params->display_header_footer = settings.display_header_footer();
params->title = settings.title();
params->url = settings.url();
}
@ -118,12 +97,6 @@ bool PrintingMessageFilter::OnMessageReceived(const IPC::Message& message,
IPC_BEGIN_MESSAGE_MAP_EX(PrintingMessageFilter, message, *message_was_ok)
#if defined(OS_WIN)
IPC_MESSAGE_HANDLER(PrintHostMsg_DuplicateSection, OnDuplicateSection)
#endif
#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
IPC_MESSAGE_HANDLER(PrintHostMsg_AllocateTempFileForPrinting,
OnAllocateTempFileForPrinting)
IPC_MESSAGE_HANDLER(PrintHostMsg_TempFileForPrintingWritten,
OnTempFileForPrintingWritten)
#endif
IPC_MESSAGE_HANDLER(PrintHostMsg_IsPrintingEnabled, OnIsPrintingEnabled)
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_GetDefaultPrintSettings,
@ -131,9 +104,6 @@ bool PrintingMessageFilter::OnMessageReceived(const IPC::Message& message,
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_ScriptedPrint, OnScriptedPrint)
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_UpdatePrintSettings,
OnUpdatePrintSettings)
#if defined(ENABLE_FULL_PRINTING)
IPC_MESSAGE_HANDLER(PrintHostMsg_CheckForCancel, OnCheckForCancel)
#endif
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@ -150,102 +120,6 @@ void PrintingMessageFilter::OnDuplicateSection(
}
#endif
#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
void PrintingMessageFilter::OnAllocateTempFileForPrinting(
int render_view_id,
base::FileDescriptor* temp_file_fd,
int* sequence_number) {
#if defined(OS_CHROMEOS)
// TODO(thestig): Use |render_view_id| for Chrome OS.
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
temp_file_fd->fd = *sequence_number = -1;
temp_file_fd->auto_close = false;
SequenceToPathMap* map = &g_printing_file_descriptor_map.Get().map;
*sequence_number = g_printing_file_descriptor_map.Get().sequence++;
base::FilePath path;
if (base::CreateTemporaryFile(&path)) {
int fd = open(path.value().c_str(), O_WRONLY);
if (fd >= 0) {
SequenceToPathMap::iterator it = map->find(*sequence_number);
if (it != map->end()) {
NOTREACHED() << "Sequence number already in use. seq=" <<
*sequence_number;
} else {
(*map)[*sequence_number] = path;
temp_file_fd->fd = fd;
temp_file_fd->auto_close = true;
}
}
}
#elif defined(OS_ANDROID)
DCHECK_CURRENTLY_ON(BrowserThread::UI);
content::WebContents* wc = GetWebContentsForRenderView(render_view_id);
if (!wc)
return;
printing::PrintViewManagerBasic* print_view_manager =
printing::PrintViewManagerBasic::FromWebContents(wc);
// The file descriptor is originally created in & passed from the Android
// side, and it will handle the closing.
const base::FileDescriptor& file_descriptor =
print_view_manager->file_descriptor();
temp_file_fd->fd = file_descriptor.fd;
temp_file_fd->auto_close = false;
#endif
}
void PrintingMessageFilter::OnTempFileForPrintingWritten(int render_view_id,
int sequence_number) {
#if defined(OS_CHROMEOS)
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
SequenceToPathMap* map = &g_printing_file_descriptor_map.Get().map;
SequenceToPathMap::iterator it = map->find(sequence_number);
if (it == map->end()) {
NOTREACHED() << "Got a sequence that we didn't pass to the "
"renderer: " << sequence_number;
return;
}
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&PrintingMessageFilter::CreatePrintDialogForFile,
this, render_view_id, it->second));
// Erase the entry in the map.
map->erase(it);
#elif defined(OS_ANDROID)
DCHECK_CURRENTLY_ON(BrowserThread::UI);
content::WebContents* wc = GetWebContentsForRenderView(render_view_id);
if (!wc)
return;
printing::PrintViewManagerBasic* print_view_manager =
printing::PrintViewManagerBasic::FromWebContents(wc);
const base::FileDescriptor& file_descriptor =
print_view_manager->file_descriptor();
printing::PrintingContextAndroid::PdfWritingDone(file_descriptor.fd, true);
// Invalidate the file descriptor so it doesn't accidentally get reused.
print_view_manager->set_file_descriptor(base::FileDescriptor(-1, false));
#endif
}
#endif // defined(OS_CHROMEOS) || defined(OS_ANDROID)
#if defined(OS_CHROMEOS)
void PrintingMessageFilter::CreatePrintDialogForFile(
int render_view_id,
const base::FilePath& path) {
content::WebContents* wc = GetWebContentsForRenderView(render_view_id);
if (!wc)
return;
print_dialog_cloud::CreatePrintDialogForFile(
wc->GetBrowserContext(),
wc->GetTopLevelNativeWindow(),
path,
wc->GetTitle(),
base::string16(),
std::string("application/pdf"));
}
#endif // defined(OS_CHROMEOS)
content::WebContents* PrintingMessageFilter::GetWebContentsForRenderView(
int render_view_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@ -410,18 +284,6 @@ void PrintingMessageFilter::OnScriptedPrintReply(
}
}
#if defined(OS_ANDROID)
void PrintingMessageFilter::UpdateFileDescriptor(int render_view_id, int fd) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
content::WebContents* wc = GetWebContentsForRenderView(render_view_id);
if (!wc)
return;
printing::PrintViewManagerBasic* print_view_manager =
printing::PrintViewManagerBasic::FromWebContents(wc);
print_view_manager->set_file_descriptor(base::FileDescriptor(fd, false));
}
#endif
void PrintingMessageFilter::OnUpdatePrintSettings(
int document_cookie, const base::DictionaryValue& job_settings,
IPC::Message* reply_msg) {
@ -464,13 +326,3 @@ void PrintingMessageFilter::OnUpdatePrintSettingsReply(
}
}
}
#if defined(ENABLE_FULL_PRINTING)
void PrintingMessageFilter::OnCheckForCancel(int32 preview_ui_id,
int preview_request_id,
bool* cancel) {
PrintPreviewUI::GetCurrentPrintPreviewStatus(preview_ui_id,
preview_request_id,
cancel);
}
#endif

View file

@ -53,25 +53,6 @@ class PrintingMessageFilter : public content::BrowserMessageFilter {
base::SharedMemoryHandle* browser_handle);
#endif
#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
// Used to ask the browser allocate a temporary file for the renderer
// to fill in resulting PDF in renderer.
void OnAllocateTempFileForPrinting(int render_view_id,
base::FileDescriptor* temp_file_fd,
int* sequence_number);
void OnTempFileForPrintingWritten(int render_view_id, int sequence_number);
#endif
#if defined(OS_CHROMEOS)
void CreatePrintDialogForFile(int render_view_id, const base::FilePath& path);
#endif
#if defined(OS_ANDROID)
// Updates the file descriptor for the PrintViewManagerBasic of a given
// render_view_id.
void UpdateFileDescriptor(int render_view_id, int fd);
#endif
// Given a render_view_id get the corresponding WebContents.
// Must be called on the UI thread.
content::WebContents* GetWebContentsForRenderView(int render_view_id);
@ -122,15 +103,6 @@ class PrintingMessageFilter : public content::BrowserMessageFilter {
scoped_refptr<printing::PrinterQuery> printer_query,
IPC::Message* reply_msg);
#if defined(ENABLE_FULL_PRINTING)
// Check to see if print preview has been cancelled.
void OnCheckForCancel(int32 preview_ui_id,
int preview_request_id,
bool* cancel);
#endif
// ProfileIOData* profile_io_data_;
const int render_process_id_;
scoped_refptr<printing::PrintQueriesQueue> queue_;

View file

@ -21,12 +21,8 @@ PrintMsg_Print_Params::PrintMsg_Print_Params()
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) {
@ -47,12 +43,8 @@ void PrintMsg_Print_Params::Reset() {
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;
@ -68,14 +60,3 @@ 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() {}

View file

@ -39,12 +39,8 @@ struct PrintMsg_Print_Params {
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;
@ -61,15 +57,6 @@ struct PrintMsg_PrintPages_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 // CHROME_COMMON_PRINT_MESSAGES_H_
#define IPC_MESSAGE_START PrintMsgStart
@ -118,26 +105,12 @@ IPC_STRUCT_TRAITS_BEGIN(PrintMsg_Print_Params)
// 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)
@ -158,13 +131,6 @@ IPC_STRUCT_BEGIN(PrintMsg_PrintPage_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)
@ -183,61 +149,6 @@ IPC_STRUCT_TRAITS_BEGIN(PrintMsg_PrintPages_Params)
IPC_STRUCT_TRAITS_MEMBER(pages)
IPC_STRUCT_TRAITS_END()
// Parameters to describe a rendered document.
IPC_STRUCT_BEGIN(PrintHostMsg_DidPreviewDocument_Params)
// 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
@ -274,19 +185,10 @@ 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)
@ -295,15 +197,6 @@ IPC_MESSAGE_ROUTED0(PrintMsg_PrintPages)
IPC_MESSAGE_ROUTED1(PrintMsg_PrintingDone,
bool /* success */)
// 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)
// Messages sent from the renderer to the browser.
#if defined(OS_WIN)
@ -369,14 +262,6 @@ IPC_MESSAGE_CONTROL2(PrintHostMsg_TempFileForPrintingWritten,
int /* fd in browser */) // Used only by Chrome OS.
#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.
@ -387,52 +272,9 @@ IPC_MESSAGE_ROUTED3(PrintHostMsg_DidGetDefaultPageLayout,
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 */)
// This is sent when there are invalid printer settings.
IPC_MESSAGE_ROUTED0(PrintHostMsg_ShowInvalidPrinterSettingsError)
// 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)

View file

@ -48,14 +48,6 @@ 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;
const char kPageLoadScriptFormat[] =
@ -286,20 +278,6 @@ bool PrintingNodeOrPdfFrame(const blink::WebFrame* 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))
@ -308,49 +286,6 @@ MarginType GetMarginsForPdf(blink::WebFrame* frame,
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;
}
// 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(
blink::WebFrame* frame,
const blink::WebNode& node,
bool source_is_html,
const base::DictionaryValue& job_settings,
const PrintMsg_Print_Params& params) {
if (params.print_to_pdf)
return blink::WebPrintScalingOptionSourceSize;
if (!source_is_html) {
if (!FitToPageEnabled(job_settings))
return blink::WebPrintScalingOptionNone;
bool no_plugin_scaling = frame->isPrintScalingDisabledForPlugin(node);
if (params.is_first_request && no_plugin_scaling)
return blink::WebPrintScalingOptionNone;
}
return blink::WebPrintScalingOptionFitToPrintableArea;
}
PrintMsg_Print_Params CalculatePrintParamsForCss(
blink::WebFrame* frame,
int page_index,
@ -394,10 +329,6 @@ PrintMsg_Print_Params CalculatePrintParamsForCss(
return result_params;
}
bool IsPrintPreviewEnabled() {
return false;
}
} // namespace
FrameReference::FrameReference(blink::WebLocalFrame* frame) {
@ -767,14 +698,11 @@ 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_print_ready_metafile_sent_(false),
ignore_css_margins_(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) {
}
@ -786,91 +714,25 @@ void PrintWebViewHelper::DidStartLoading() {
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 (is_preview_enabled_) {
print_preview_context_.InitWithFrame(frame);
RequestPrintPreview(PRINT_PREVIEW_SCRIPTED);
} else {
Print(frame, blink::WebNode());
}
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_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>/<iframe> 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;
}
// The out-of-process plugin element is nested within a frame.
blink::WebLocalFrame* plugin_frame = pdf_element.document().frame();
blink::WebElement plugin_element = pdf_element;
// Set |print_for_preview_| flag and autoreset it to back to original
// on return.
base::AutoReset<bool> set_printing_flag(&print_for_preview_, true);
if (!UpdatePrintSettings(plugin_frame, plugin_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(plugin_frame, plugin_element)) {
LOG(ERROR) << "RenderPagesForPrint failed";
DidFinishPrinting(FAIL_PRINT);
}
}
bool PrintWebViewHelper::GetPrintFrame(blink::WebLocalFrame** frame) {
DCHECK(frame);
blink::WebView* webView = render_view()->GetWebView();
@ -894,16 +756,6 @@ void PrintWebViewHelper::OnPrintPages() {
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,
@ -937,199 +789,6 @@ bool PrintWebViewHelper::IsPrintToPdfRequested(
return print_to_pdf;
}
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 (!print_preview_context_.source_frame()) {
DidFinishPrinting(FAIL_PREVIEW);
return;
}
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_.get()
? print_pages_params_->params.document_cookie
: 0));
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.
PreviewMetafile* metafile = print_preview_context_.metafile();
uint32 buf_size = metafile->GetDataSize();
DCHECK_GT(buf_size, 0u);
PrintHostMsg_DidPreviewDocument_Params preview_params;
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)
@ -1137,17 +796,6 @@ void PrintWebViewHelper::OnPrintingDone(bool success) {
DidFinishPrinting(success ? OK : FAIL_PRINT);
}
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));
@ -1172,13 +820,8 @@ void PrintWebViewHelper::PrintNode(const blink::WebNode& node) {
// 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);
}
blink::WebNode duplicate_node(node);
Print(duplicate_node.document().frame(), duplicate_node);
print_node_in_progress_ = false;
}
@ -1232,19 +875,6 @@ void PrintWebViewHelper::DidFinishPrinting(PrintingResult result) {
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();
@ -1278,18 +908,6 @@ void PrintWebViewHelper::PrintPages() {
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.";
@ -1398,99 +1016,6 @@ bool PrintWebViewHelper::CalculateNumberOfPages(blink::WebLocalFrame* frame,
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
Send(new PrintHostMsg_ShowInvalidPrinterSettingsError(routing_id()));
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(
frame, node, 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) {
@ -1505,8 +1030,6 @@ bool PrintWebViewHelper::GetPrintSettingsFromUser(blink::WebFrame* frame,
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 =
@ -1563,359 +1086,4 @@ bool PrintWebViewHelper::CopyMetafileDataToSharedMem(
}
#endif // defined(OS_POSIX)
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 {
// TODO(japhet): This delay is a terrible hack. See crbug.com/376969
// for the motivation.
base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&PrintWebViewHelper::ShowScriptedPrintPreview,
weak_ptr_factory_.GetWeakPtr()),
base::TimeDelta::FromMilliseconds(100));
}
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,
Metafile* 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 PreviewMetafile);
if (!metafile_->Init()) {
set_error(PREVIEW_ERROR_METAFILE_INIT_FAILED);
LOG(ERROR) << "PreviewMetafile 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(state_ != UNINITIALIZED);
return source_frame_.GetFrame();
}
const blink::WebNode&
PrintWebViewHelper::PrintPreviewContext::source_node() const {
DCHECK(state_ != UNINITIALIZED);
return source_node_;
}
blink::WebLocalFrame*
PrintWebViewHelper::PrintPreviewContext::prepared_frame() {
DCHECK(state_ != UNINITIALIZED);
return prep_frame_view_->frame();
}
const blink::WebNode&
PrintWebViewHelper::PrintPreviewContext::prepared_node() const {
DCHECK(state_ != UNINITIALIZED);
return prep_frame_view_->node();
}
int PrintWebViewHelper::PrintPreviewContext::total_page_count() const {
DCHECK(state_ != UNINITIALIZED);
return total_page_count_;
}
bool PrintWebViewHelper::PrintPreviewContext::generate_draft_pages() const {
return generate_draft_pages_;
}
PreviewMetafile* 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

View file

@ -88,27 +88,6 @@ class PrintWebViewHelper
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.
@ -121,9 +100,6 @@ class PrintWebViewHelper
// 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
@ -139,23 +115,6 @@ class PrintWebViewHelper
// Returns true if the current destination printer is PRINT_TO_PDF.
bool IsPrintToPdfRequested(const base::DictionaryValue& settings);
// 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);
@ -178,13 +137,6 @@ class PrintWebViewHelper
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,
@ -276,22 +228,6 @@ class PrintWebViewHelper
// Script Initiated Printing ------------------------------------------------
// 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, Metafile* metafile);
// WebView used only to print the selection.
scoped_ptr<PrepareFrameAndViewForPrint> prep_frame_view_;
bool reset_prep_frame_view_;
@ -306,124 +242,11 @@ class PrintWebViewHelper
// 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;
PreviewMetafile* 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<PreviewMetafile> 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_;

View file

@ -26,37 +26,6 @@ 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<Metafile> draft_metafile;
Metafile* initial_render_metafile = print_preview_context_.metafile();
if (print_preview_context_.IsModifiable() && is_print_ready_metafile_sent_) {
draft_metafile.reset(new PreviewMetafile);
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.reset(
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) {
@ -162,8 +131,7 @@ void PrintWebViewHelper::PrintPageInternal(
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;
gfx::Rect canvas_area = content_area;
SkBaseDevice* device = metafile->StartPageForVectorCanvas(page_size,
canvas_area,
@ -178,15 +146,6 @@ void PrintWebViewHelper::PrintPageInternal(
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.get(), 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.get());

View file

@ -54,47 +54,6 @@ void PrintWebViewHelper::PrintPageInternal(
Send(new PrintHostMsg_DidPrintPage(routing_id(), page_params));
}
bool PrintWebViewHelper::RenderPreviewPage(
int page_number,
const PrintMsg_Print_Params& print_params) {
PrintMsg_Print_Params printParams = print_params;
scoped_ptr<Metafile> draft_metafile;
Metafile* initial_render_metafile = print_preview_context_.metafile();
bool render_to_draft = print_preview_context_.IsModifiable() &&
is_print_ready_metafile_sent_;
if (render_to_draft) {
draft_metafile.reset(new PreviewMetafile());
if (!draft_metafile->Init()) {
print_preview_context_.set_error(
PREVIEW_ERROR_MAC_DRAFT_METAFILE_INIT_FAILED);
LOG(ERROR) << "Draft PreviewMetafile Init failed";
return false;
}
initial_render_metafile = draft_metafile.get();
}
base::TimeTicks begin_time = base::TimeTicks::Now();
gfx::Size page_size;
RenderPage(printParams, page_number, print_preview_context_.prepared_frame(),
true, initial_render_metafile, &page_size, NULL);
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.reset(
print_preview_context_.metafile()->GetMetafileForCurrentPage());
}
}
return PreviewPageRendered(page_number, draft_metafile.get());
}
void PrintWebViewHelper::RenderPage(
const PrintMsg_Print_Params& params, int page_number, WebFrame* frame,
bool is_preview, Metafile* metafile, gfx::Size* page_size,
@ -114,8 +73,7 @@ void PrintWebViewHelper::RenderPage(
scale_factor *= webkit_shrink_factor;
gfx::Rect canvas_area =
params.display_header_footer ? gfx::Rect(*page_size) : content_area;
gfx::Rect canvas_area = content_area;
{
SkBaseDevice* device = metafile->StartPageForVectorCanvas(
@ -130,12 +88,6 @@ void PrintWebViewHelper::RenderPage(
skia::SetIsDraftMode(*canvas, is_print_ready_metafile_sent_);
skia::SetIsPreviewMetafile(*canvas, is_preview);
if (print_pages_params_->params.display_header_footer) {
PrintHeaderAndFooter(canvas_ptr, page_number + 1,
print_preview_context_.total_page_count(),
scale_factor, page_layout_in_points,
*header_footer_info_, params);
}
RenderPageContent(frame, page_number, canvas_area, content_area,
scale_factor, canvas_ptr);
}

View file

@ -88,37 +88,6 @@ void PrintWebViewHelper::PrintPageInternal(
Send(new PrintHostMsg_DidPrintPage(routing_id(), page_params));
}
bool PrintWebViewHelper::RenderPreviewPage(
int page_number,
const PrintMsg_Print_Params& print_params) {
// Calculate the dpi adjustment.
double actual_shrink = static_cast<float>(print_params.desired_dpi /
print_params.dpi);
scoped_ptr<Metafile> draft_metafile;
Metafile* initial_render_metafile = print_preview_context_.metafile();
if (print_preview_context_.IsModifiable() && is_print_ready_metafile_sent_) {
draft_metafile.reset(new PreviewMetafile);
initial_render_metafile = draft_metafile.get();
}
base::TimeTicks begin_time = base::TimeTicks::Now();
RenderPage(print_params, page_number, print_preview_context_.prepared_frame(),
true, initial_render_metafile, &actual_shrink, NULL, NULL);
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.reset(
print_preview_context_.metafile()->GetMetafileForCurrentPage());
}
return PreviewPageRendered(page_number, draft_metafile.get());
}
void PrintWebViewHelper::RenderPage(
const PrintMsg_Print_Params& params, int page_number, WebFrame* frame,
bool is_preview, Metafile* metafile, double* actual_shrink,
@ -154,22 +123,10 @@ void PrintWebViewHelper::RenderPage(
kPointsPerInch, dpi)));
}
if (!is_preview) {
// Since WebKit extends the page width depending on the magical scale factor
// we make sure the canvas covers the worst case scenario (x2.0 currently).
// PrintContext will then set the correct clipping region.
page_size = gfx::Size(
static_cast<int>(page_layout_in_points.content_width *
params.max_shrink),
static_cast<int>(page_layout_in_points.content_height *
params.max_shrink));
}
float webkit_page_shrink_factor = frame->getPrintPageShrink(page_number);
float scale_factor = css_scale_factor * webkit_page_shrink_factor;
gfx::Rect canvas_area =
params.display_header_footer ? gfx::Rect(page_size) : content_area;
gfx::Rect canvas_area = content_area;
SkBaseDevice* device = metafile->StartPageForVectorCanvas(
page_size, canvas_area, scale_factor);
@ -179,19 +136,6 @@ void PrintWebViewHelper::RenderPage(
skia::RefPtr<skia::VectorCanvas> canvas =
skia::AdoptRef(new skia::VectorCanvas(device));
if (is_preview) {
MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile);
skia::SetIsDraftMode(*canvas, is_print_ready_metafile_sent_);
skia::SetIsPreviewMetafile(*canvas, is_preview);
}
if (params.display_header_footer) {
// |page_number| is 0-based, so 1 is added.
PrintHeaderAndFooter(canvas.get(), page_number + 1,
print_preview_context_.total_page_count(), scale_factor,
page_layout_in_points, *header_footer_info_, params);
}
float webkit_scale_factor = RenderPageContent(frame, page_number, canvas_area,
content_area, scale_factor,
canvas.get());