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

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: Mon Aug 25 23:50:54 PDT 2014 Created 6 years, 3 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 "chrome/grit/generated_resources.h" 17 #include "chrome/grit/generated_resources.h"
18 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/notification_service.h" 19 #include "content/public/browser/notification_service.h"
20 #include "content/public/browser/render_view_host.h"
21 #include "content/public/browser/web_contents.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 scoped_ptr<PrintingUIWebContentsObserver> web_contents_observer_;
52 base::WeakPtrFactory<PrintingContextDelegate> weak_ptr_factory_;
53 };
54
55 PrintingContextDelegate::PrintingContextDelegate(int render_process_id,
56 int render_view_id)
57 : weak_ptr_factory_(this) {
58 InitOnUiThread(render_process_id, render_view_id);
59 }
60
61 PrintingContextDelegate::~PrintingContextDelegate() {
62 DCHECK_CURRENTLY_ON(BrowserThread::UI);
63 }
64
65 gfx::NativeView PrintingContextDelegate::GetParentView() {
66 DCHECK_CURRENTLY_ON(BrowserThread::UI);
67 if (!web_contents_observer_)
68 return NULL;
69 return web_contents_observer_->GetParentView();
70 }
71
72 std::string PrintingContextDelegate::GetAppLocale() {
73 return g_browser_process->GetApplicationLocale();
74 }
75
76 void PrintingContextDelegate::InitOnUiThread(int render_process_id,
77 int render_view_id) {
78 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
79 // All data initialized here should be accessed on UI thread. Because object
80 // is being constructed now, anything that is going to access
81 // PrintingContextDelegate on UI thread would be scheduled after the tasks
82 // below.
83 BrowserThread::PostTask(BrowserThread::UI,
84 FROM_HERE,
85 base::Bind(&PrintingContextDelegate::InitOnUiThread,
86 weak_ptr_factory_.GetWeakPtr(),
87 render_process_id,
88 render_view_id));
89 return;
90 }
91 content::RenderViewHost* view =
92 content::RenderViewHost::FromID(render_process_id, render_view_id);
93 if (!view)
94 return;
95 content::WebContents* wc = content::WebContents::FromRenderViewHost(view);
96 if (!wc)
97 return;
98 web_contents_observer_.reset(new PrintingUIWebContentsObserver(wc));
99 }
39 100
40 void NotificationCallback(PrintJobWorkerOwner* print_job, 101 void NotificationCallback(PrintJobWorkerOwner* print_job,
41 JobEventDetails::Type detail_type, 102 JobEventDetails::Type detail_type,
42 PrintedDocument* document, 103 PrintedDocument* document,
43 PrintedPage* page) { 104 PrintedPage* page) {
44 JobEventDetails* details = new JobEventDetails(detail_type, document, page); 105 JobEventDetails* details = new JobEventDetails(detail_type, document, page);
45 content::NotificationService::current()->Notify( 106 content::NotificationService::current()->Notify(
46 chrome::NOTIFICATION_PRINT_JOB_EVENT, 107 chrome::NOTIFICATION_PRINT_JOB_EVENT,
47 // We know that is is a PrintJob object in this circumstance. 108 // We know that is is a PrintJob object in this circumstance.
48 content::Source<PrintJob>(static_cast<PrintJob*>(print_job)), 109 content::Source<PrintJob>(static_cast<PrintJob*>(print_job)),
49 content::Details<JobEventDetails>(details)); 110 content::Details<JobEventDetails>(details));
50 } 111 }
51 112
52 PrintJobWorker::PrintJobWorker(PrintJobWorkerOwner* owner) 113 } // namespace
114
115 PrintJobWorker::PrintJobWorker(int render_process_id,
116 int render_view_id,
117 PrintJobWorkerOwner* owner)
53 : owner_(owner), thread_("Printing_Worker"), weak_factory_(this) { 118 : owner_(owner), thread_("Printing_Worker"), weak_factory_(this) {
54 // The object is created in the IO thread. 119 // The object is created in the IO thread.
55 DCHECK(owner_->RunsTasksOnCurrentThread()); 120 DCHECK(owner_->RunsTasksOnCurrentThread());
56 121
57 printing_context_.reset(PrintingContext::Create( 122 printing_context_delegate_.reset(
58 g_browser_process->GetApplicationLocale())); 123 new PrintingContextDelegate(render_process_id, render_view_id));
124 printing_context_ = PrintingContext::Create(printing_context_delegate_.get());
59 } 125 }
60 126
61 PrintJobWorker::~PrintJobWorker() { 127 PrintJobWorker::~PrintJobWorker() {
62 // The object is normally deleted in the UI thread, but when the user 128 // 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 129 // cancels printing or in the case of print preview, the worker is destroyed
64 // on the I/O thread. 130 // on the I/O thread.
65 DCHECK(owner_->RunsTasksOnCurrentThread()); 131 DCHECK(owner_->RunsTasksOnCurrentThread());
66 Stop(); 132 Stop();
67 } 133 }
68 134
69 void PrintJobWorker::SetNewOwner(PrintJobWorkerOwner* new_owner) { 135 void PrintJobWorker::SetNewOwner(PrintJobWorkerOwner* new_owner) {
70 DCHECK(page_number_ == PageNumber::npos()); 136 DCHECK(page_number_ == PageNumber::npos());
71 owner_ = new_owner; 137 owner_ = new_owner;
72 } 138 }
73 139
74 void PrintJobWorker::SetPrintDestination( 140 void PrintJobWorker::SetPrintDestination(
75 PrintDestinationInterface* destination) { 141 PrintDestinationInterface* destination) {
76 destination_ = destination; 142 destination_ = destination;
77 } 143 }
78 144
79 void PrintJobWorker::GetSettings( 145 void PrintJobWorker::GetSettings(
80 bool ask_user_for_settings, 146 bool ask_user_for_settings,
81 scoped_ptr<PrintingUIWebContentsObserver> web_contents_observer,
82 int document_page_count, 147 int document_page_count,
83 bool has_selection, 148 bool has_selection,
84 MarginType margin_type) { 149 MarginType margin_type) {
85 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 150 DCHECK(task_runner_->RunsTasksOnCurrentThread());
86 DCHECK_EQ(page_number_, PageNumber::npos()); 151 DCHECK_EQ(page_number_, PageNumber::npos());
87 152
88 // Recursive task processing is needed for the dialog in case it needs to be 153 // Recursive task processing is needed for the dialog in case it needs to be
89 // destroyed by a task. 154 // destroyed by a task.
90 // TODO(thestig): This code is wrong. SetNestableTasksAllowed(true) is needed 155 // TODO(thestig): This code is wrong. SetNestableTasksAllowed(true) is needed
91 // on the thread where the PrintDlgEx is called, and definitely both calls 156 // on the thread where the PrintDlgEx is called, and definitely both calls
92 // should happen on the same thread. See http://crbug.com/73466 157 // should happen on the same thread. See http://crbug.com/73466
93 // MessageLoop::current()->SetNestableTasksAllowed(true); 158 // MessageLoop::current()->SetNestableTasksAllowed(true);
94 printing_context_->set_margin_type(margin_type); 159 printing_context_->set_margin_type(margin_type);
95 160
96 // When we delegate to a destination, we don't ask the user for settings. 161 // When we delegate to a destination, we don't ask the user for settings.
97 // TODO(mad): Ask the destination for settings. 162 // TODO(mad): Ask the destination for settings.
98 if (ask_user_for_settings && destination_.get() == NULL) { 163 if (ask_user_for_settings && destination_.get() == NULL) {
99 BrowserThread::PostTask( 164 BrowserThread::PostTask(
100 BrowserThread::UI, FROM_HERE, 165 BrowserThread::UI, FROM_HERE,
101 base::Bind(&HoldRefCallback, make_scoped_refptr(owner_), 166 base::Bind(&HoldRefCallback, make_scoped_refptr(owner_),
102 base::Bind(&PrintJobWorker::GetSettingsWithUI, 167 base::Bind(&PrintJobWorker::GetSettingsWithUI,
103 base::Unretained(this), 168 base::Unretained(this),
104 base::Passed(&web_contents_observer),
105 document_page_count, 169 document_page_count,
106 has_selection))); 170 has_selection)));
107 } else { 171 } else {
108 BrowserThread::DeleteSoon(
109 BrowserThread::UI, FROM_HERE, web_contents_observer.release());
110 BrowserThread::PostTask( 172 BrowserThread::PostTask(
111 BrowserThread::UI, FROM_HERE, 173 BrowserThread::UI, FROM_HERE,
112 base::Bind(&HoldRefCallback, make_scoped_refptr(owner_), 174 base::Bind(&HoldRefCallback, make_scoped_refptr(owner_),
113 base::Bind(&PrintJobWorker::UseDefaultSettings, 175 base::Bind(&PrintJobWorker::UseDefaultSettings,
114 base::Unretained(this)))); 176 base::Unretained(this))));
115 } 177 }
116 } 178 }
117 179
118 void PrintJobWorker::SetSettings( 180 void PrintJobWorker::SetSettings(
119 scoped_ptr<base::DictionaryValue> new_settings) { 181 scoped_ptr<base::DictionaryValue> new_settings) {
120 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 182 DCHECK(task_runner_->RunsTasksOnCurrentThread());
121 183
122 BrowserThread::PostTask( 184 BrowserThread::PostTask(
123 BrowserThread::UI, 185 BrowserThread::UI,
124 FROM_HERE, 186 FROM_HERE,
125 base::Bind(&HoldRefCallback, 187 base::Bind(&HoldRefCallback,
126 make_scoped_refptr(owner_), 188 make_scoped_refptr(owner_),
127 base::Bind(&PrintJobWorker::UpdatePrintSettings, 189 base::Bind(&PrintJobWorker::UpdatePrintSettings,
128 base::Unretained(this), 190 base::Unretained(this),
129 base::Passed(&new_settings)))); 191 base::Passed(&new_settings))));
130 } 192 }
131 193
132 void PrintJobWorker::UpdatePrintSettings( 194 void PrintJobWorker::UpdatePrintSettings(
133 scoped_ptr<base::DictionaryValue> new_settings) { 195 scoped_ptr<base::DictionaryValue> new_settings) {
196 DCHECK_CURRENTLY_ON(BrowserThread::UI);
134 PrintingContext::Result result = 197 PrintingContext::Result result =
135 printing_context_->UpdatePrintSettings(*new_settings); 198 printing_context_->UpdatePrintSettings(*new_settings);
136 GetSettingsDone(result); 199 GetSettingsDone(result);
137 } 200 }
138 201
139 void PrintJobWorker::GetSettingsDone(PrintingContext::Result result) { 202 void PrintJobWorker::GetSettingsDone(PrintingContext::Result result) {
140 // Most PrintingContext functions may start a message loop and process 203 // Most PrintingContext functions may start a message loop and process
141 // message recursively, so disable recursive task processing. 204 // message recursively, so disable recursive task processing.
142 // TODO(thestig): See above comment. SetNestableTasksAllowed(false) needs to 205 // TODO(thestig): See above comment. SetNestableTasksAllowed(false) needs to
143 // be called on the same thread as the previous call. See 206 // be called on the same thread as the previous call. See
144 // http://crbug.com/73466 207 // http://crbug.com/73466
145 // MessageLoop::current()->SetNestableTasksAllowed(false); 208 // MessageLoop::current()->SetNestableTasksAllowed(false);
146 209
147 // We can't use OnFailure() here since owner_ may not support notifications. 210 // We can't use OnFailure() here since owner_ may not support notifications.
148 211
149 // PrintJob will create the new PrintedDocument. 212 // PrintJob will create the new PrintedDocument.
150 owner_->PostTask(FROM_HERE, 213 owner_->PostTask(FROM_HERE,
151 base::Bind(&PrintJobWorkerOwner::GetSettingsDone, 214 base::Bind(&PrintJobWorkerOwner::GetSettingsDone,
152 make_scoped_refptr(owner_), 215 make_scoped_refptr(owner_),
153 printing_context_->settings(), 216 printing_context_->settings(),
154 result)); 217 result));
155 } 218 }
156 219
157 void PrintJobWorker::GetSettingsWithUI( 220 void PrintJobWorker::GetSettingsWithUI(
158 scoped_ptr<PrintingUIWebContentsObserver> web_contents_observer,
159 int document_page_count, 221 int document_page_count,
160 bool has_selection) { 222 bool has_selection) {
161 DCHECK_CURRENTLY_ON(BrowserThread::UI); 223 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( 224 printing_context_->AskUserForSettings(
169 parent_view, document_page_count, has_selection, 225 document_page_count,
226 has_selection,
170 base::Bind(&PrintJobWorker::GetSettingsWithUIDone, 227 base::Bind(&PrintJobWorker::GetSettingsWithUIDone,
171 base::Unretained(this))); 228 base::Unretained(this)));
172 } 229 }
173 230
174 void PrintJobWorker::GetSettingsWithUIDone(PrintingContext::Result result) { 231 void PrintJobWorker::GetSettingsWithUIDone(PrintingContext::Result result) {
175 PostTask(FROM_HERE, 232 PostTask(FROM_HERE,
176 base::Bind(&HoldRefCallback, 233 base::Bind(&HoldRefCallback,
177 make_scoped_refptr(owner_), 234 make_scoped_refptr(owner_),
178 base::Bind(&PrintJobWorker::GetSettingsDone, 235 base::Bind(&PrintJobWorker::GetSettingsDone,
179 base::Unretained(this), 236 base::Unretained(this),
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 366 DCHECK(task_runner_->RunsTasksOnCurrentThread());
310 DCHECK_EQ(page_number_, PageNumber::npos()); 367 DCHECK_EQ(page_number_, PageNumber::npos());
311 DCHECK(document_.get()); 368 DCHECK(document_.get());
312 369
313 if (printing_context_->DocumentDone() != PrintingContext::OK) { 370 if (printing_context_->DocumentDone() != PrintingContext::OK) {
314 OnFailure(); 371 OnFailure();
315 return; 372 return;
316 } 373 }
317 374
318 owner_->PostTask(FROM_HERE, 375 owner_->PostTask(FROM_HERE,
319 base::Bind(NotificationCallback, 376 base::Bind(&NotificationCallback,
320 make_scoped_refptr(owner_), 377 make_scoped_refptr(owner_),
321 JobEventDetails::DOC_DONE, 378 JobEventDetails::DOC_DONE,
322 document_, 379 document_,
323 scoped_refptr<PrintedPage>())); 380 scoped_refptr<PrintedPage>()));
324 381
325 // Makes sure the variables are reinitialized. 382 // Makes sure the variables are reinitialized.
326 document_ = NULL; 383 document_ = NULL;
327 } 384 }
328 385
329 void PrintJobWorker::SpoolPage(PrintedPage* page) { 386 void PrintJobWorker::SpoolPage(PrintedPage* page) {
330 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 387 DCHECK(task_runner_->RunsTasksOnCurrentThread());
331 DCHECK_NE(page_number_, PageNumber::npos()); 388 DCHECK_NE(page_number_, PageNumber::npos());
332 389
333 // Signal everyone that the page is about to be printed. 390 // Signal everyone that the page is about to be printed.
334 owner_->PostTask(FROM_HERE, 391 owner_->PostTask(FROM_HERE,
335 base::Bind(NotificationCallback, 392 base::Bind(&NotificationCallback,
336 make_scoped_refptr(owner_), 393 make_scoped_refptr(owner_),
337 JobEventDetails::NEW_PAGE, 394 JobEventDetails::NEW_PAGE,
338 document_, 395 document_,
339 make_scoped_refptr(page))); 396 make_scoped_refptr(page)));
340 397
341 // Preprocess. 398 // Preprocess.
342 if (printing_context_->NewPage() != PrintingContext::OK) { 399 if (printing_context_->NewPage() != PrintingContext::OK) {
343 OnFailure(); 400 OnFailure();
344 return; 401 return;
345 } 402 }
(...skipping 18 matching lines...) Expand all
364 #endif 421 #endif
365 422
366 // Postprocess. 423 // Postprocess.
367 if (printing_context_->PageDone() != PrintingContext::OK) { 424 if (printing_context_->PageDone() != PrintingContext::OK) {
368 OnFailure(); 425 OnFailure();
369 return; 426 return;
370 } 427 }
371 428
372 // Signal everyone that the page is printed. 429 // Signal everyone that the page is printed.
373 owner_->PostTask(FROM_HERE, 430 owner_->PostTask(FROM_HERE,
374 base::Bind(NotificationCallback, 431 base::Bind(&NotificationCallback,
375 make_scoped_refptr(owner_), 432 make_scoped_refptr(owner_),
376 JobEventDetails::PAGE_DONE, 433 JobEventDetails::PAGE_DONE,
377 document_, 434 document_,
378 make_scoped_refptr(page))); 435 make_scoped_refptr(page)));
379 } 436 }
380 437
381 void PrintJobWorker::OnFailure() { 438 void PrintJobWorker::OnFailure() {
382 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 439 DCHECK(task_runner_->RunsTasksOnCurrentThread());
383 440
384 // We may loose our last reference by broadcasting the FAILED event. 441 // We may loose our last reference by broadcasting the FAILED event.
385 scoped_refptr<PrintJobWorkerOwner> handle(owner_); 442 scoped_refptr<PrintJobWorkerOwner> handle(owner_);
386 443
387 owner_->PostTask(FROM_HERE, 444 owner_->PostTask(FROM_HERE,
388 base::Bind(NotificationCallback, 445 base::Bind(&NotificationCallback,
389 make_scoped_refptr(owner_), 446 make_scoped_refptr(owner_),
390 JobEventDetails::FAILED, 447 JobEventDetails::FAILED,
391 document_, 448 document_,
392 scoped_refptr<PrintedPage>())); 449 scoped_refptr<PrintedPage>()));
393 Cancel(); 450 Cancel();
394 451
395 // Makes sure the variables are reinitialized. 452 // Makes sure the variables are reinitialized.
396 document_ = NULL; 453 document_ = NULL;
397 page_number_ = PageNumber::npos(); 454 page_number_ = PageNumber::npos();
398 } 455 }
399 456
400 } // namespace printing 457 } // 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