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/printer_query.h"
8 #include "base/bind_helpers.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/threading/thread_restrictions.h"
11 #include "base/values.h"
12 #include "chrome/browser/printing/print_job_worker.h"
16 PrinterQuery::PrinterQuery(int render_process_id
, int render_view_id
)
17 : worker_(new PrintJobWorker(render_process_id
, render_view_id
, this)),
18 is_print_dialog_box_shown_(false),
19 cookie_(PrintSettings::NewCookie()),
20 last_status_(PrintingContext::FAILED
) {
21 DCHECK(base::MessageLoopForIO::IsCurrent());
24 PrinterQuery::~PrinterQuery() {
25 // The job should be finished (or at least canceled) when it is destroyed.
26 DCHECK(!is_print_dialog_box_shown_
);
27 // If this fires, it is that this pending printer context has leaked.
28 DCHECK(!worker_
.get());
31 void PrinterQuery::GetSettingsDone(const PrintSettings
& new_settings
,
32 PrintingContext::Result result
) {
33 is_print_dialog_box_shown_
= false;
34 last_status_
= result
;
35 if (result
!= PrintingContext::FAILED
) {
36 settings_
= new_settings
;
37 cookie_
= PrintSettings::NewCookie();
43 if (!callback_
.is_null()) {
44 // This may cause reentrancy like to call StopWorker().
50 PrintJobWorker
* PrinterQuery::DetachWorker(PrintJobWorkerOwner
* new_owner
) {
51 DCHECK(callback_
.is_null());
52 DCHECK(worker_
.get());
54 worker_
->SetNewOwner(new_owner
);
55 return worker_
.release();
58 const PrintSettings
& PrinterQuery::settings() const {
62 int PrinterQuery::cookie() const {
66 void PrinterQuery::GetSettings(
67 GetSettingsAskParam ask_user_for_settings
,
68 int expected_page_count
,
70 MarginType margin_type
,
72 const base::Closure
& callback
) {
73 DCHECK(RunsTasksOnCurrentThread());
74 DCHECK(!is_print_dialog_box_shown_
|| !is_scripted
);
76 StartWorker(callback
);
78 // Real work is done in PrintJobWorker::GetSettings().
79 is_print_dialog_box_shown_
=
80 ask_user_for_settings
== GetSettingsAskParam::ASK_USER
;
81 worker_
->PostTask(FROM_HERE
,
82 base::Bind(&PrintJobWorker::GetSettings
,
83 base::Unretained(worker_
.get()),
84 is_print_dialog_box_shown_
,
91 void PrinterQuery::SetSettings(scoped_ptr
<base::DictionaryValue
> new_settings
,
92 const base::Closure
& callback
) {
93 StartWorker(callback
);
95 worker_
->PostTask(FROM_HERE
,
96 base::Bind(&PrintJobWorker::SetSettings
,
97 base::Unretained(worker_
.get()),
98 base::Passed(&new_settings
)));
101 void PrinterQuery::StartWorker(const base::Closure
& callback
) {
102 DCHECK(callback_
.is_null());
103 DCHECK(worker_
.get());
105 // Lazily create the worker thread. There is one worker thread per print job.
106 if (!worker_
->IsRunning())
109 callback_
= callback
;
112 void PrinterQuery::StopWorker() {
114 // http://crbug.com/66082: We're blocking on the PrinterQuery's worker
115 // thread. It's not clear to me if this may result in blocking the current
116 // thread for an unacceptable time. We should probably fix it.
117 base::ThreadRestrictions::ScopedAllowIO allow_io
;
123 bool PrinterQuery::is_callback_pending() const {
124 return !callback_
.is_null();
127 bool PrinterQuery::is_valid() const {
128 return worker_
.get() != NULL
;
131 } // namespace printing