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"
10 #include "base/lazy_instance.h"
11 #include "base/metrics/histogram.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/printing/print_job_manager.h"
14 #include "chrome/browser/printing/print_preview_dialog_controller.h"
15 #include "chrome/browser/printing/print_view_manager_observer.h"
16 #include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
17 #include "chrome/common/print_messages.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/web_contents.h"
20 #include "printing/print_destination_interface.h"
22 using content::BrowserThread;
24 DEFINE_WEB_CONTENTS_USER_DATA_KEY(printing::PrintViewManager);
28 // Keeps track of pending scripted print preview closures.
29 // No locking, only access on the UI thread.
30 typedef std::map<content::RenderProcessHost*, base::Closure>
31 ScriptedPrintPreviewClosureMap;
32 static base::LazyInstance<ScriptedPrintPreviewClosureMap>
33 g_scripted_print_preview_closure_map = LAZY_INSTANCE_INITIALIZER;
39 PrintViewManager::PrintViewManager(content::WebContents* web_contents)
40 : PrintViewManagerBase(web_contents),
42 print_preview_state_(NOT_PREVIEWING),
43 scripted_print_preview_rph_(NULL) {
46 PrintViewManager::~PrintViewManager() {
47 DCHECK_EQ(NOT_PREVIEWING, print_preview_state_);
50 bool PrintViewManager::PrintForSystemDialogNow() {
51 return PrintNowInternal(new PrintMsg_PrintForSystemDialog(routing_id()));
54 bool PrintViewManager::AdvancedPrintNow() {
55 PrintPreviewDialogController* dialog_controller =
56 PrintPreviewDialogController::GetInstance();
57 if (!dialog_controller)
59 content::WebContents* print_preview_dialog =
60 dialog_controller->GetPrintPreviewForContents(web_contents());
61 if (print_preview_dialog) {
62 if (!print_preview_dialog->GetWebUI())
64 PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>(
65 print_preview_dialog->GetWebUI()->GetController());
66 print_preview_ui->OnShowSystemDialog();
73 bool PrintViewManager::PrintToDestination() {
74 // TODO(mad): Remove this once we can send user metrics from the metro driver.
76 UMA_HISTOGRAM_ENUMERATION("Metro.Print", 0, 2);
77 // TODO(mad): Use a passed in destination interface instead.
78 g_browser_process->print_job_manager()->queue()->SetDestination(
79 printing::CreatePrintDestination());
80 return PrintNowInternal(new PrintMsg_PrintPages(routing_id()));
83 bool PrintViewManager::PrintPreviewNow(bool selection_only) {
84 // Users can send print commands all they want and it is beyond
85 // PrintViewManager's control. Just ignore the extra commands.
86 // See http://crbug.com/136842 for example.
87 if (print_preview_state_ != NOT_PREVIEWING)
90 if (!PrintNowInternal(new PrintMsg_InitiatePrintPreview(routing_id(),
95 print_preview_state_ = USER_INITIATED_PREVIEW;
99 void PrintViewManager::PrintPreviewForWebNode() {
100 if (print_preview_state_ != NOT_PREVIEWING)
102 print_preview_state_ = USER_INITIATED_PREVIEW;
105 void PrintViewManager::PrintPreviewDone() {
106 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
107 DCHECK_NE(NOT_PREVIEWING, print_preview_state_);
109 if (print_preview_state_ == SCRIPTED_PREVIEW) {
110 ScriptedPrintPreviewClosureMap& map =
111 g_scripted_print_preview_closure_map.Get();
112 ScriptedPrintPreviewClosureMap::iterator it =
113 map.find(scripted_print_preview_rph_);
114 CHECK(it != map.end());
116 map.erase(scripted_print_preview_rph_);
117 scripted_print_preview_rph_ = NULL;
119 print_preview_state_ = NOT_PREVIEWING;
122 void PrintViewManager::set_observer(PrintViewManagerObserver* observer) {
123 DCHECK(!observer || !observer_);
124 observer_ = observer;
127 void PrintViewManager::RenderProcessGone(base::TerminationStatus status) {
128 print_preview_state_ = NOT_PREVIEWING;
129 PrintViewManagerBase::RenderProcessGone(status);
132 void PrintViewManager::OnDidShowPrintDialog() {
134 observer_->OnPrintDialogShown();
137 void PrintViewManager::OnSetupScriptedPrintPreview(IPC::Message* reply_msg) {
138 BrowserThread::CurrentlyOn(BrowserThread::UI);
139 ScriptedPrintPreviewClosureMap& map =
140 g_scripted_print_preview_closure_map.Get();
141 content::RenderProcessHost* rph = web_contents()->GetRenderProcessHost();
143 // This should always be 0 once we get modal window.print().
144 if (map.count(rph) != 0) {
145 // Renderer already handling window.print() in another View.
149 if (print_preview_state_ != NOT_PREVIEWING) {
150 // If a user initiated print dialog is already open, ignore the scripted
152 DCHECK_EQ(USER_INITIATED_PREVIEW, print_preview_state_);
157 PrintPreviewDialogController* dialog_controller =
158 PrintPreviewDialogController::GetInstance();
159 if (!dialog_controller) {
164 print_preview_state_ = SCRIPTED_PREVIEW;
165 base::Closure callback =
166 base::Bind(&PrintViewManager::OnScriptedPrintPreviewReply,
167 base::Unretained(this),
170 scripted_print_preview_rph_ = rph;
173 void PrintViewManager::OnShowScriptedPrintPreview(bool source_is_modifiable) {
174 PrintPreviewDialogController* dialog_controller =
175 PrintPreviewDialogController::GetInstance();
176 if (!dialog_controller) {
180 dialog_controller->PrintPreview(web_contents());
181 PrintHostMsg_RequestPrintPreview_Params params;
182 params.is_modifiable = source_is_modifiable;
183 PrintPreviewUI::SetInitialParams(
184 dialog_controller->GetPrintPreviewForContents(web_contents()), params);
187 void PrintViewManager::OnScriptedPrintPreviewReply(IPC::Message* reply_msg) {
188 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
192 bool PrintViewManager::OnMessageReceived(const IPC::Message& message) {
194 IPC_BEGIN_MESSAGE_MAP(PrintViewManager, message)
195 IPC_MESSAGE_HANDLER(PrintHostMsg_DidShowPrintDialog, OnDidShowPrintDialog)
196 IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_SetupScriptedPrintPreview,
197 OnSetupScriptedPrintPreview)
198 IPC_MESSAGE_HANDLER(PrintHostMsg_ShowScriptedPrintPreview,
199 OnShowScriptedPrintPreview)
200 IPC_MESSAGE_UNHANDLED(handled = false)
201 IPC_END_MESSAGE_MAP()
203 return handled ? true : PrintViewManagerBase::OnMessageReceived(message);
206 } // namespace printing