Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(455)

Side by Side Diff: chrome/browser/printing/print_job_worker.cc

Issue 478183005: Added PrintingContext::Delegate to get parent view handle and application locale. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Wed Aug 20 16:46:22 PDT 2014 Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/printing/print_job_worker.h ('k') | chrome/browser/printing/printer_query.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/printing/print_job_worker.h" 5 #include "chrome/browser/printing/print_job_worker.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
11 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "base/values.h" 12 #include "base/values.h"
13 #include "chrome/browser/browser_process.h" 13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/chrome_notification_types.h" 14 #include "chrome/browser/chrome_notification_types.h"
15 #include "chrome/browser/printing/print_job.h" 15 #include "chrome/browser/printing/print_job.h"
16 #include "chrome/browser/printing/printing_ui_web_contents_observer.h" 16 #include "chrome/browser/printing/printing_ui_web_contents_observer.h"
17 #include "content/public/browser/browser_thread.h" 17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/notification_service.h" 18 #include "content/public/browser/notification_service.h"
19 #include "content/public/browser/render_view_host.h"
20 #include "content/public/browser/web_contents.h"
19 #include "grit/generated_resources.h" 21 #include "grit/generated_resources.h"
20 #include "printing/print_job_constants.h" 22 #include "printing/print_job_constants.h"
21 #include "printing/printed_document.h" 23 #include "printing/printed_document.h"
22 #include "printing/printed_page.h" 24 #include "printing/printed_page.h"
23 #include "printing/printing_utils.h" 25 #include "printing/printing_utils.h"
24 #include "ui/base/l10n/l10n_util.h" 26 #include "ui/base/l10n/l10n_util.h"
25 27
26 using content::BrowserThread; 28 using content::BrowserThread;
27 29
28 namespace printing { 30 namespace printing {
29 31
30 namespace { 32 namespace {
31 33
32 // Helper function to ensure |owner| is valid until at least |callback| returns. 34 // Helper function to ensure |owner| is valid until at least |callback| returns.
33 void HoldRefCallback(const scoped_refptr<printing::PrintJobWorkerOwner>& owner, 35 void HoldRefCallback(const scoped_refptr<printing::PrintJobWorkerOwner>& owner,
34 const base::Closure& callback) { 36 const base::Closure& callback) {
35 callback.Run(); 37 callback.Run();
36 } 38 }
37 39
38 } // namespace 40 class PrintingContextDelegate : public PrintingContext::Delegate {
41 public:
42 PrintingContextDelegate(int render_process_id, int render_view_id);
43 virtual ~PrintingContextDelegate();
44
45 virtual gfx::NativeView GetParentView() OVERRIDE;
46 virtual std::string GetAppLocale() OVERRIDE;
47
48 private:
49 void InitOnUiThread(int render_process_id, int render_view_id);
50
51 base::WeakPtrFactory<PrintingContextDelegate> weak_ptr_factory_;
Noam Samuel 2014/08/21 00:03:53 Should be last.
Vitaly Buka (NO REVIEWS) 2014/08/21 01:19:16 Done.
52 scoped_ptr<PrintingUIWebContentsObserver> web_contents_observer_;
53 };
54
55 PrintingContextDelegate::PrintingContextDelegate(int render_process_id,
56 int render_view_id)
57 : weak_ptr_factory_(this) {
58 BrowserThread::PostTask(BrowserThread::UI,
59 FROM_HERE,
60 base::Bind(&PrintingContextDelegate::InitOnUiThread,
61 weak_ptr_factory_.GetWeakPtr(),
62 render_process_id,
63 render_view_id));
64 }
65
66 PrintingContextDelegate::~PrintingContextDelegate() {
67 DCHECK_CURRENTLY_ON(BrowserThread::UI);
68 }
69
70 gfx::NativeView PrintingContextDelegate::GetParentView() {
71 DCHECK_CURRENTLY_ON(BrowserThread::UI);
72 if (!web_contents_observer_)
73 return NULL;
74 return web_contents_observer_->GetParentView();
75 }
76
77 std::string PrintingContextDelegate::GetAppLocale() {
78 return g_browser_process->GetApplicationLocale();
79 }
80
81 void PrintingContextDelegate::InitOnUiThread(int render_process_id,
82 int render_view_id) {
83 DCHECK_CURRENTLY_ON(BrowserThread::UI);
84 content::RenderViewHost* view =
85 content::RenderViewHost::FromID(render_process_id, render_view_id);
86 if (!view)
87 return;
88 content::WebContents* wc = content::WebContents::FromRenderViewHost(view);
89 if (!wc)
90 return;
91 web_contents_observer_.reset(new PrintingUIWebContentsObserver(wc));
92 }
39 93
40 void NotificationCallback(PrintJobWorkerOwner* print_job, 94 void NotificationCallback(PrintJobWorkerOwner* print_job,
41 JobEventDetails::Type detail_type, 95 JobEventDetails::Type detail_type,
42 PrintedDocument* document, 96 PrintedDocument* document,
43 PrintedPage* page) { 97 PrintedPage* page) {
44 JobEventDetails* details = new JobEventDetails(detail_type, document, page); 98 JobEventDetails* details = new JobEventDetails(detail_type, document, page);
45 content::NotificationService::current()->Notify( 99 content::NotificationService::current()->Notify(
46 chrome::NOTIFICATION_PRINT_JOB_EVENT, 100 chrome::NOTIFICATION_PRINT_JOB_EVENT,
47 // We know that is is a PrintJob object in this circumstance. 101 // We know that is is a PrintJob object in this circumstance.
48 content::Source<PrintJob>(static_cast<PrintJob*>(print_job)), 102 content::Source<PrintJob>(static_cast<PrintJob*>(print_job)),
49 content::Details<JobEventDetails>(details)); 103 content::Details<JobEventDetails>(details));
50 } 104 }
51 105
52 PrintJobWorker::PrintJobWorker(PrintJobWorkerOwner* owner) 106 } // namespace
107
108 PrintJobWorker::PrintJobWorker(int render_process_id,
109 int render_view_id,
110 PrintJobWorkerOwner* owner)
53 : owner_(owner), thread_("Printing_Worker"), weak_factory_(this) { 111 : owner_(owner), thread_("Printing_Worker"), weak_factory_(this) {
54 // The object is created in the IO thread. 112 // The object is created in the IO thread.
55 DCHECK(owner_->RunsTasksOnCurrentThread()); 113 DCHECK(owner_->RunsTasksOnCurrentThread());
56 114
57 printing_context_.reset(PrintingContext::Create( 115 printing_context_delegate_.reset(
58 g_browser_process->GetApplicationLocale())); 116 new PrintingContextDelegate(render_process_id, render_view_id));
117 printing_context_ = PrintingContext::Create(printing_context_delegate_.get());
59 } 118 }
60 119
61 PrintJobWorker::~PrintJobWorker() { 120 PrintJobWorker::~PrintJobWorker() {
62 // The object is normally deleted in the UI thread, but when the user 121 // The object is normally deleted in the UI thread, but when the user
63 // cancels printing or in the case of print preview, the worker is destroyed 122 // cancels printing or in the case of print preview, the worker is destroyed
64 // on the I/O thread. 123 // on the I/O thread.
65 DCHECK(owner_->RunsTasksOnCurrentThread()); 124 DCHECK(owner_->RunsTasksOnCurrentThread());
66 Stop(); 125 Stop();
126 printing_context_.reset();
127 BrowserThread::DeleteSoon(
Noam Samuel 2014/08/21 00:03:53 Can also use scoped ptr with custom deleter maybe?
Vitaly Buka (NO REVIEWS) 2014/08/21 01:19:16 Current deleter for scoper_refptr. I'll try to cha
128 BrowserThread::UI, FROM_HERE, printing_context_delegate_.release());
67 } 129 }
68 130
69 void PrintJobWorker::SetNewOwner(PrintJobWorkerOwner* new_owner) { 131 void PrintJobWorker::SetNewOwner(PrintJobWorkerOwner* new_owner) {
70 DCHECK(page_number_ == PageNumber::npos()); 132 DCHECK(page_number_ == PageNumber::npos());
71 owner_ = new_owner; 133 owner_ = new_owner;
72 } 134 }
73 135
74 void PrintJobWorker::SetPrintDestination( 136 void PrintJobWorker::SetPrintDestination(
75 PrintDestinationInterface* destination) { 137 PrintDestinationInterface* destination) {
76 destination_ = destination; 138 destination_ = destination;
77 } 139 }
78 140
79 void PrintJobWorker::GetSettings( 141 void PrintJobWorker::GetSettings(
80 bool ask_user_for_settings, 142 bool ask_user_for_settings,
81 scoped_ptr<PrintingUIWebContentsObserver> web_contents_observer,
82 int document_page_count, 143 int document_page_count,
83 bool has_selection, 144 bool has_selection,
84 MarginType margin_type) { 145 MarginType margin_type) {
85 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 146 DCHECK(task_runner_->RunsTasksOnCurrentThread());
86 DCHECK_EQ(page_number_, PageNumber::npos()); 147 DCHECK_EQ(page_number_, PageNumber::npos());
87 148
88 // Recursive task processing is needed for the dialog in case it needs to be 149 // Recursive task processing is needed for the dialog in case it needs to be
89 // destroyed by a task. 150 // destroyed by a task.
90 // TODO(thestig): This code is wrong. SetNestableTasksAllowed(true) is needed 151 // TODO(thestig): This code is wrong. SetNestableTasksAllowed(true) is needed
91 // on the thread where the PrintDlgEx is called, and definitely both calls 152 // on the thread where the PrintDlgEx is called, and definitely both calls
92 // should happen on the same thread. See http://crbug.com/73466 153 // should happen on the same thread. See http://crbug.com/73466
93 // MessageLoop::current()->SetNestableTasksAllowed(true); 154 // MessageLoop::current()->SetNestableTasksAllowed(true);
94 printing_context_->set_margin_type(margin_type); 155 printing_context_->set_margin_type(margin_type);
95 156
96 // When we delegate to a destination, we don't ask the user for settings. 157 // When we delegate to a destination, we don't ask the user for settings.
97 // TODO(mad): Ask the destination for settings. 158 // TODO(mad): Ask the destination for settings.
98 if (ask_user_for_settings && destination_.get() == NULL) { 159 if (ask_user_for_settings && destination_.get() == NULL) {
99 BrowserThread::PostTask( 160 BrowserThread::PostTask(
100 BrowserThread::UI, FROM_HERE, 161 BrowserThread::UI, FROM_HERE,
101 base::Bind(&HoldRefCallback, make_scoped_refptr(owner_), 162 base::Bind(&HoldRefCallback, make_scoped_refptr(owner_),
102 base::Bind(&PrintJobWorker::GetSettingsWithUI, 163 base::Bind(&PrintJobWorker::GetSettingsWithUI,
103 base::Unretained(this), 164 base::Unretained(this),
104 base::Passed(&web_contents_observer),
105 document_page_count, 165 document_page_count,
106 has_selection))); 166 has_selection)));
107 } else { 167 } else {
108 BrowserThread::DeleteSoon(
109 BrowserThread::UI, FROM_HERE, web_contents_observer.release());
110 BrowserThread::PostTask( 168 BrowserThread::PostTask(
111 BrowserThread::UI, FROM_HERE, 169 BrowserThread::UI, FROM_HERE,
112 base::Bind(&HoldRefCallback, make_scoped_refptr(owner_), 170 base::Bind(&HoldRefCallback, make_scoped_refptr(owner_),
113 base::Bind(&PrintJobWorker::UseDefaultSettings, 171 base::Bind(&PrintJobWorker::UseDefaultSettings,
114 base::Unretained(this)))); 172 base::Unretained(this))));
115 } 173 }
116 } 174 }
117 175
118 void PrintJobWorker::SetSettings( 176 void PrintJobWorker::SetSettings(
119 scoped_ptr<base::DictionaryValue> new_settings) { 177 scoped_ptr<base::DictionaryValue> new_settings) {
120 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 178 DCHECK(task_runner_->RunsTasksOnCurrentThread());
121 179
122 BrowserThread::PostTask( 180 BrowserThread::PostTask(
123 BrowserThread::UI, 181 BrowserThread::UI,
124 FROM_HERE, 182 FROM_HERE,
125 base::Bind(&HoldRefCallback, 183 base::Bind(&HoldRefCallback,
126 make_scoped_refptr(owner_), 184 make_scoped_refptr(owner_),
127 base::Bind(&PrintJobWorker::UpdatePrintSettings, 185 base::Bind(&PrintJobWorker::UpdatePrintSettings,
128 base::Unretained(this), 186 base::Unretained(this),
129 base::Passed(&new_settings)))); 187 base::Passed(&new_settings))));
130 } 188 }
131 189
132 void PrintJobWorker::UpdatePrintSettings( 190 void PrintJobWorker::UpdatePrintSettings(
133 scoped_ptr<base::DictionaryValue> new_settings) { 191 scoped_ptr<base::DictionaryValue> new_settings) {
192 DCHECK_CURRENTLY_ON(BrowserThread::UI);
134 PrintingContext::Result result = 193 PrintingContext::Result result =
135 printing_context_->UpdatePrintSettings(*new_settings); 194 printing_context_->UpdatePrintSettings(*new_settings);
136 GetSettingsDone(result); 195 GetSettingsDone(result);
137 } 196 }
138 197
139 void PrintJobWorker::GetSettingsDone(PrintingContext::Result result) { 198 void PrintJobWorker::GetSettingsDone(PrintingContext::Result result) {
140 // Most PrintingContext functions may start a message loop and process 199 // Most PrintingContext functions may start a message loop and process
141 // message recursively, so disable recursive task processing. 200 // message recursively, so disable recursive task processing.
142 // TODO(thestig): See above comment. SetNestableTasksAllowed(false) needs to 201 // TODO(thestig): See above comment. SetNestableTasksAllowed(false) needs to
143 // be called on the same thread as the previous call. See 202 // be called on the same thread as the previous call. See
144 // http://crbug.com/73466 203 // http://crbug.com/73466
145 // MessageLoop::current()->SetNestableTasksAllowed(false); 204 // MessageLoop::current()->SetNestableTasksAllowed(false);
146 205
147 // We can't use OnFailure() here since owner_ may not support notifications. 206 // We can't use OnFailure() here since owner_ may not support notifications.
148 207
149 // PrintJob will create the new PrintedDocument. 208 // PrintJob will create the new PrintedDocument.
150 owner_->PostTask(FROM_HERE, 209 owner_->PostTask(FROM_HERE,
151 base::Bind(&PrintJobWorkerOwner::GetSettingsDone, 210 base::Bind(&PrintJobWorkerOwner::GetSettingsDone,
152 make_scoped_refptr(owner_), 211 make_scoped_refptr(owner_),
153 printing_context_->settings(), 212 printing_context_->settings(),
154 result)); 213 result));
155 } 214 }
156 215
157 void PrintJobWorker::GetSettingsWithUI( 216 void PrintJobWorker::GetSettingsWithUI(
158 scoped_ptr<PrintingUIWebContentsObserver> web_contents_observer,
159 int document_page_count, 217 int document_page_count,
160 bool has_selection) { 218 bool has_selection) {
161 DCHECK_CURRENTLY_ON(BrowserThread::UI); 219 DCHECK_CURRENTLY_ON(BrowserThread::UI);
162
163 gfx::NativeView parent_view = web_contents_observer->GetParentView();
164 if (!parent_view) {
165 GetSettingsWithUIDone(printing::PrintingContext::FAILED);
166 return;
167 }
168 printing_context_->AskUserForSettings( 220 printing_context_->AskUserForSettings(
169 parent_view, document_page_count, has_selection, 221 document_page_count,
222 has_selection,
170 base::Bind(&PrintJobWorker::GetSettingsWithUIDone, 223 base::Bind(&PrintJobWorker::GetSettingsWithUIDone,
171 base::Unretained(this))); 224 base::Unretained(this)));
172 } 225 }
173 226
174 void PrintJobWorker::GetSettingsWithUIDone(PrintingContext::Result result) { 227 void PrintJobWorker::GetSettingsWithUIDone(PrintingContext::Result result) {
175 PostTask(FROM_HERE, 228 PostTask(FROM_HERE,
176 base::Bind(&HoldRefCallback, 229 base::Bind(&HoldRefCallback,
177 make_scoped_refptr(owner_), 230 make_scoped_refptr(owner_),
178 base::Bind(&PrintJobWorker::GetSettingsDone, 231 base::Bind(&PrintJobWorker::GetSettingsDone,
179 base::Unretained(this), 232 base::Unretained(this),
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 362 DCHECK(task_runner_->RunsTasksOnCurrentThread());
310 DCHECK_EQ(page_number_, PageNumber::npos()); 363 DCHECK_EQ(page_number_, PageNumber::npos());
311 DCHECK(document_.get()); 364 DCHECK(document_.get());
312 365
313 if (printing_context_->DocumentDone() != PrintingContext::OK) { 366 if (printing_context_->DocumentDone() != PrintingContext::OK) {
314 OnFailure(); 367 OnFailure();
315 return; 368 return;
316 } 369 }
317 370
318 owner_->PostTask(FROM_HERE, 371 owner_->PostTask(FROM_HERE,
319 base::Bind(NotificationCallback, 372 base::Bind(&NotificationCallback,
320 make_scoped_refptr(owner_), 373 make_scoped_refptr(owner_),
321 JobEventDetails::DOC_DONE, 374 JobEventDetails::DOC_DONE,
322 document_, 375 document_,
323 scoped_refptr<PrintedPage>())); 376 scoped_refptr<PrintedPage>()));
324 377
325 // Makes sure the variables are reinitialized. 378 // Makes sure the variables are reinitialized.
326 document_ = NULL; 379 document_ = NULL;
327 } 380 }
328 381
329 void PrintJobWorker::SpoolPage(PrintedPage* page) { 382 void PrintJobWorker::SpoolPage(PrintedPage* page) {
330 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 383 DCHECK(task_runner_->RunsTasksOnCurrentThread());
331 DCHECK_NE(page_number_, PageNumber::npos()); 384 DCHECK_NE(page_number_, PageNumber::npos());
332 385
333 // Signal everyone that the page is about to be printed. 386 // Signal everyone that the page is about to be printed.
334 owner_->PostTask(FROM_HERE, 387 owner_->PostTask(FROM_HERE,
335 base::Bind(NotificationCallback, 388 base::Bind(&NotificationCallback,
336 make_scoped_refptr(owner_), 389 make_scoped_refptr(owner_),
337 JobEventDetails::NEW_PAGE, 390 JobEventDetails::NEW_PAGE,
338 document_, 391 document_,
339 make_scoped_refptr(page))); 392 make_scoped_refptr(page)));
340 393
341 // Preprocess. 394 // Preprocess.
342 if (printing_context_->NewPage() != PrintingContext::OK) { 395 if (printing_context_->NewPage() != PrintingContext::OK) {
343 OnFailure(); 396 OnFailure();
344 return; 397 return;
345 } 398 }
(...skipping 18 matching lines...) Expand all
364 #endif 417 #endif
365 418
366 // Postprocess. 419 // Postprocess.
367 if (printing_context_->PageDone() != PrintingContext::OK) { 420 if (printing_context_->PageDone() != PrintingContext::OK) {
368 OnFailure(); 421 OnFailure();
369 return; 422 return;
370 } 423 }
371 424
372 // Signal everyone that the page is printed. 425 // Signal everyone that the page is printed.
373 owner_->PostTask(FROM_HERE, 426 owner_->PostTask(FROM_HERE,
374 base::Bind(NotificationCallback, 427 base::Bind(&NotificationCallback,
375 make_scoped_refptr(owner_), 428 make_scoped_refptr(owner_),
376 JobEventDetails::PAGE_DONE, 429 JobEventDetails::PAGE_DONE,
377 document_, 430 document_,
378 make_scoped_refptr(page))); 431 make_scoped_refptr(page)));
379 } 432 }
380 433
381 void PrintJobWorker::OnFailure() { 434 void PrintJobWorker::OnFailure() {
382 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 435 DCHECK(task_runner_->RunsTasksOnCurrentThread());
383 436
384 // We may loose our last reference by broadcasting the FAILED event. 437 // We may loose our last reference by broadcasting the FAILED event.
385 scoped_refptr<PrintJobWorkerOwner> handle(owner_); 438 scoped_refptr<PrintJobWorkerOwner> handle(owner_);
386 439
387 owner_->PostTask(FROM_HERE, 440 owner_->PostTask(FROM_HERE,
388 base::Bind(NotificationCallback, 441 base::Bind(&NotificationCallback,
389 make_scoped_refptr(owner_), 442 make_scoped_refptr(owner_),
390 JobEventDetails::FAILED, 443 JobEventDetails::FAILED,
391 document_, 444 document_,
392 scoped_refptr<PrintedPage>())); 445 scoped_refptr<PrintedPage>()));
393 Cancel(); 446 Cancel();
394 447
395 // Makes sure the variables are reinitialized. 448 // Makes sure the variables are reinitialized.
396 document_ = NULL; 449 document_ = NULL;
397 page_number_ = PageNumber::npos(); 450 page_number_ = PageNumber::npos();
398 } 451 }
399 452
400 } // namespace printing 453 } // namespace printing
OLDNEW
« no previous file with comments | « chrome/browser/printing/print_job_worker.h ('k') | chrome/browser/printing/printer_query.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698