1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "android_webview/browser/renderer_host/print_manager.h"
6
7#include "android_webview/browser/aw_browser_context.h"
8#include "android_webview/common/print_messages.h"
9#include "android_webview/common/render_view_messages.h"
10#include "base/android/scoped_java_ref.h"
11#include "base/callback.h"
12#include "base/files/file_util.h"
13#include "base/logging.h"
14#include "content/public/browser/browser_thread.h"
15#include "printing/print_settings.h"
16
17using content::BrowserThread;
18using printing::PrintSettings;
19
20namespace android_webview {
21
22PrintManager::PrintManager(content::WebContents* contents,
23                           PrintSettings* settings,
24                           int fd,
25                           PrintManagerDelegate* delegate)
26    : content::WebContentsObserver(contents),
27      settings_(settings),
28      fd_(fd),
29      delegate_(delegate),
30      number_pages_(0),
31      cookie_(1),
32      printing_(false) {
33  DCHECK(delegate_);
34}
35
36PrintManager::~PrintManager() {}
37
38bool PrintManager::OnMessageReceived(const IPC::Message& message) {
39  bool handled = true;
40  IPC_BEGIN_MESSAGE_MAP(PrintManager, message)
41    IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPrintedPagesCount,
42                        OnDidGetPrintedPagesCount)
43    IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetDocumentCookie,
44                        OnDidGetDocumentCookie)
45    IPC_MESSAGE_HANDLER(PrintHostMsg_PrintingFailed, OnPrintingFailed)
46    IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_GetDefaultPrintSettings,
47                                    OnGetDefaultPrintSettings)
48    IPC_MESSAGE_HANDLER(PrintHostMsg_AllocateTempFileForPrinting,
49                        OnAllocateTempFileForPrinting)
50    IPC_MESSAGE_HANDLER(PrintHostMsg_TempFileForPrintingWritten,
51                        OnTempFileForPrintingWritten)
52    IPC_MESSAGE_UNHANDLED(handled = false)
53  IPC_END_MESSAGE_MAP()
54
55  return handled ? true : WebContentsObserver::OnMessageReceived(message);
56}
57
58void PrintManager::OnAllocateTempFileForPrinting(
59    base::FileDescriptor* temp_file_fd,
60    int* sequence_number) {
61  // we don't really use the sequence number.
62  *sequence_number = 0;
63  temp_file_fd->fd = fd_;
64  temp_file_fd->auto_close = false;
65}
66
67void PrintManager::OnTempFileForPrintingWritten(int sequence_number) {
68  delegate_->DidExportPdf(true);
69}
70
71void PrintManager::OnDidGetPrintedPagesCount(int cookie,
72                                             int number_pages) {
73  DCHECK_GT(cookie, 0);
74  DCHECK_GT(number_pages, 0);
75  number_pages_ = number_pages;
76}
77
78void PrintManager::OnDidGetDocumentCookie(int cookie) {
79  cookie_ = cookie;
80}
81
82void PrintManager::OnGetDefaultPrintSettings(IPC::Message* reply_msg) {
83  // Unlike the printing_message_filter, we do process this in ui thread
84  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
85  OnGetDefaultPrintSettingsReply(reply_msg);
86}
87
88void RenderParamsFromPrintSettings(const printing::PrintSettings& settings,
89                                   PrintMsg_Print_Params* params) {
90  params->page_size = settings.page_setup_device_units().physical_size();
91  params->content_size.SetSize(
92      settings.page_setup_device_units().content_area().width(),
93      settings.page_setup_device_units().content_area().height());
94  params->printable_area.SetRect(
95      settings.page_setup_device_units().printable_area().x(),
96      settings.page_setup_device_units().printable_area().y(),
97      settings.page_setup_device_units().printable_area().width(),
98      settings.page_setup_device_units().printable_area().height());
99  params->margin_top = settings.page_setup_device_units().content_area().y();
100  params->margin_left = settings.page_setup_device_units().content_area().x();
101  params->dpi = settings.dpi();
102  // Currently hardcoded at 1.25. See PrintSettings' constructor.
103  params->min_shrink = settings.min_shrink();
104  // Currently hardcoded at 2.0. See PrintSettings' constructor.
105  params->max_shrink = settings.max_shrink();
106  // Currently hardcoded at 72dpi. See PrintSettings' constructor.
107  params->desired_dpi = settings.desired_dpi();
108  // Always use an invalid cookie.
109  params->document_cookie = 0;
110  params->selection_only = settings.selection_only();
111  params->supports_alpha_blend = settings.supports_alpha_blend();
112  params->should_print_backgrounds = settings.should_print_backgrounds();
113  params->display_header_footer = settings.display_header_footer();
114  params->title = settings.title();
115  params->url = settings.url();
116}
117
118void PrintManager::OnGetDefaultPrintSettingsReply(IPC::Message* reply_msg) {
119  PrintMsg_Print_Params params;
120  RenderParamsFromPrintSettings(*settings_, &params);
121  params.document_cookie = cookie_;
122  PrintHostMsg_GetDefaultPrintSettings::WriteReplyParams(reply_msg, params);
123  Send(reply_msg);
124}
125
126void PrintManager::OnPrintingFailed(int cookie) {
127  if (cookie != cookie_) {
128    NOTREACHED();
129    return;
130  }
131  delegate_->DidExportPdf(false);
132}
133
134bool PrintManager::PrintNow() {
135  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
136  if (printing_)
137    return false;
138
139  printing_ = true;
140  return Send(new PrintMsg_PrintPages(routing_id()));
141}
142
143}  // namespace android_webview
144