QUIC - cleanup changes to sync chromium tree with internal source.
[chromium-blink-merge.git] / chrome / browser / printing / print_view_manager.cc
blob8fdf54ddcb33f195d341d50fb21a62e7430ffc7b
1 // Copyright (c) 2012 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.
5 #include "chrome/browser/printing/print_view_manager.h"
7 #include <map>
9 #include "base/bind.h"
10 #include "base/lazy_instance.h"
11 #include "base/metrics/histogram.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/plugins/chrome_plugin_service_filter.h"
14 #include "chrome/browser/printing/print_job_manager.h"
15 #include "chrome/browser/printing/print_preview_dialog_controller.h"
16 #include "chrome/browser/printing/print_view_manager_observer.h"
17 #include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
18 #include "chrome/common/chrome_content_client.h"
19 #include "components/printing/common/print_messages.h"
20 #include "content/public/browser/browser_thread.h"
21 #include "content/public/browser/plugin_service.h"
22 #include "content/public/browser/render_frame_host.h"
23 #include "content/public/browser/render_process_host.h"
24 #include "content/public/browser/web_contents.h"
25 #include "content/public/common/webplugininfo.h"
27 using content::BrowserThread;
29 DEFINE_WEB_CONTENTS_USER_DATA_KEY(printing::PrintViewManager);
31 namespace {
33 // Keeps track of pending scripted print preview closures.
34 // No locking, only access on the UI thread.
35 typedef std::map<content::RenderProcessHost*, base::Closure>
36 ScriptedPrintPreviewClosureMap;
37 static base::LazyInstance<ScriptedPrintPreviewClosureMap>
38 g_scripted_print_preview_closure_map = LAZY_INSTANCE_INITIALIZER;
40 void EnableInternalPDFPluginForContents(int render_process_id,
41 int render_frame_id) {
42 // Always enable the internal PDF plugin for the print preview page.
43 base::FilePath pdf_plugin_path = base::FilePath::FromUTF8Unsafe(
44 ChromeContentClient::kPDFPluginPath);
46 content::WebPluginInfo pdf_plugin;
47 if (!content::PluginService::GetInstance()->GetPluginInfoByPath(
48 pdf_plugin_path, &pdf_plugin)) {
49 return;
52 ChromePluginServiceFilter::GetInstance()->OverridePluginForFrame(
53 render_process_id, render_frame_id, GURL(), pdf_plugin);
56 } // namespace
58 namespace printing {
60 PrintViewManager::PrintViewManager(content::WebContents* web_contents)
61 : PrintViewManagerBase(web_contents),
62 observer_(NULL),
63 print_preview_state_(NOT_PREVIEWING),
64 scripted_print_preview_rph_(NULL) {
65 if (PrintPreviewDialogController::IsPrintPreviewDialog(web_contents)) {
66 EnableInternalPDFPluginForContents(
67 web_contents->GetRenderProcessHost()->GetID(),
68 web_contents->GetMainFrame()->GetRoutingID());
72 PrintViewManager::~PrintViewManager() {
73 DCHECK_EQ(NOT_PREVIEWING, print_preview_state_);
76 #if defined(ENABLE_BASIC_PRINTING)
77 bool PrintViewManager::PrintForSystemDialogNow() {
78 return PrintNowInternal(new PrintMsg_PrintForSystemDialog(routing_id()));
81 bool PrintViewManager::BasicPrint() {
82 PrintPreviewDialogController* dialog_controller =
83 PrintPreviewDialogController::GetInstance();
84 if (!dialog_controller)
85 return false;
86 content::WebContents* print_preview_dialog =
87 dialog_controller->GetPrintPreviewForContents(web_contents());
88 if (print_preview_dialog) {
89 if (!print_preview_dialog->GetWebUI())
90 return false;
91 PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>(
92 print_preview_dialog->GetWebUI()->GetController());
93 print_preview_ui->OnShowSystemDialog();
94 return true;
95 } else {
96 return PrintNow();
99 #endif // ENABLE_BASIC_PRINTING
101 bool PrintViewManager::PrintPreviewNow(bool selection_only) {
102 // Users can send print commands all they want and it is beyond
103 // PrintViewManager's control. Just ignore the extra commands.
104 // See http://crbug.com/136842 for example.
105 if (print_preview_state_ != NOT_PREVIEWING)
106 return false;
108 if (!PrintNowInternal(new PrintMsg_InitiatePrintPreview(routing_id(),
109 selection_only))) {
110 return false;
113 print_preview_state_ = USER_INITIATED_PREVIEW;
114 return true;
117 void PrintViewManager::PrintPreviewForWebNode() {
118 if (print_preview_state_ != NOT_PREVIEWING)
119 return;
120 print_preview_state_ = USER_INITIATED_PREVIEW;
123 void PrintViewManager::PrintPreviewDone() {
124 DCHECK_CURRENTLY_ON(BrowserThread::UI);
125 DCHECK_NE(NOT_PREVIEWING, print_preview_state_);
127 if (print_preview_state_ == SCRIPTED_PREVIEW) {
128 ScriptedPrintPreviewClosureMap& map =
129 g_scripted_print_preview_closure_map.Get();
130 ScriptedPrintPreviewClosureMap::iterator it =
131 map.find(scripted_print_preview_rph_);
132 CHECK(it != map.end());
133 it->second.Run();
134 map.erase(scripted_print_preview_rph_);
135 scripted_print_preview_rph_ = NULL;
137 print_preview_state_ = NOT_PREVIEWING;
140 void PrintViewManager::set_observer(PrintViewManagerObserver* observer) {
141 DCHECK(!observer || !observer_);
142 observer_ = observer;
145 void PrintViewManager::RenderFrameCreated(
146 content::RenderFrameHost* render_frame_host) {
147 if (PrintPreviewDialogController::IsPrintPreviewDialog(web_contents())) {
148 EnableInternalPDFPluginForContents(render_frame_host->GetProcess()->GetID(),
149 render_frame_host->GetRoutingID());
153 void PrintViewManager::RenderProcessGone(base::TerminationStatus status) {
154 print_preview_state_ = NOT_PREVIEWING;
155 PrintViewManagerBase::RenderProcessGone(status);
158 void PrintViewManager::OnDidShowPrintDialog() {
159 if (observer_)
160 observer_->OnPrintDialogShown();
163 void PrintViewManager::OnSetupScriptedPrintPreview(IPC::Message* reply_msg) {
164 DCHECK_CURRENTLY_ON(BrowserThread::UI);
165 ScriptedPrintPreviewClosureMap& map =
166 g_scripted_print_preview_closure_map.Get();
167 content::RenderProcessHost* rph = web_contents()->GetRenderProcessHost();
169 // This should always be 0 once we get modal window.print().
170 if (map.count(rph) != 0) {
171 // Renderer already handling window.print() in another View.
172 Send(reply_msg);
173 return;
175 if (print_preview_state_ != NOT_PREVIEWING) {
176 // If a user initiated print dialog is already open, ignore the scripted
177 // print message.
178 DCHECK_EQ(USER_INITIATED_PREVIEW, print_preview_state_);
179 Send(reply_msg);
180 return;
183 PrintPreviewDialogController* dialog_controller =
184 PrintPreviewDialogController::GetInstance();
185 if (!dialog_controller) {
186 Send(reply_msg);
187 return;
190 print_preview_state_ = SCRIPTED_PREVIEW;
191 base::Closure callback =
192 base::Bind(&PrintViewManager::OnScriptedPrintPreviewReply,
193 base::Unretained(this),
194 reply_msg);
195 map[rph] = callback;
196 scripted_print_preview_rph_ = rph;
199 void PrintViewManager::OnShowScriptedPrintPreview(bool source_is_modifiable) {
200 PrintPreviewDialogController* dialog_controller =
201 PrintPreviewDialogController::GetInstance();
202 if (!dialog_controller) {
203 PrintPreviewDone();
204 return;
206 dialog_controller->PrintPreview(web_contents());
207 PrintHostMsg_RequestPrintPreview_Params params;
208 params.is_modifiable = source_is_modifiable;
209 PrintPreviewUI::SetInitialParams(
210 dialog_controller->GetPrintPreviewForContents(web_contents()), params);
213 void PrintViewManager::OnScriptedPrintPreviewReply(IPC::Message* reply_msg) {
214 DCHECK_CURRENTLY_ON(BrowserThread::UI);
215 Send(reply_msg);
218 bool PrintViewManager::OnMessageReceived(const IPC::Message& message) {
219 bool handled = true;
220 IPC_BEGIN_MESSAGE_MAP(PrintViewManager, message)
221 IPC_MESSAGE_HANDLER(PrintHostMsg_DidShowPrintDialog, OnDidShowPrintDialog)
222 IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_SetupScriptedPrintPreview,
223 OnSetupScriptedPrintPreview)
224 IPC_MESSAGE_HANDLER(PrintHostMsg_ShowScriptedPrintPreview,
225 OnShowScriptedPrintPreview)
226 IPC_MESSAGE_UNHANDLED(handled = false)
227 IPC_END_MESSAGE_MAP()
229 return handled ? true : PrintViewManagerBase::OnMessageReceived(message);
232 } // namespace printing