Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / printing / printer_query.cc
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.
4
5 #include "chrome/browser/printing/printer_query.h"
6
7 #include "base/bind.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"
13 #include "chrome/browser/printing/printing_ui_web_contents_observer.h"
14
15 namespace printing {
16
17 PrinterQuery::PrinterQuery()
18     : io_message_loop_(base::MessageLoop::current()),
19       worker_(new PrintJobWorker(this)),
20       is_print_dialog_box_shown_(false),
21       cookie_(PrintSettings::NewCookie()),
22       last_status_(PrintingContext::FAILED) {
23   DCHECK(base::MessageLoopForIO::IsCurrent());
24 }
25
26 PrinterQuery::~PrinterQuery() {
27   // The job should be finished (or at least canceled) when it is destroyed.
28   DCHECK(!is_print_dialog_box_shown_);
29   // If this fires, it is that this pending printer context has leaked.
30   DCHECK(!worker_.get());
31 }
32
33 void PrinterQuery::GetSettingsDone(const PrintSettings& new_settings,
34                                    PrintingContext::Result result) {
35   is_print_dialog_box_shown_ = false;
36   last_status_ = result;
37   if (result != PrintingContext::FAILED) {
38     settings_ = new_settings;
39     cookie_ = PrintSettings::NewCookie();
40   } else {
41     // Failure.
42     cookie_ = 0;
43   }
44
45   if (!callback_.is_null()) {
46     // This may cause reentrancy like to call StopWorker().
47     callback_.Run();
48     callback_.Reset();
49   }
50 }
51
52 PrintJobWorker* PrinterQuery::DetachWorker(PrintJobWorkerOwner* new_owner) {
53   DCHECK(callback_.is_null());
54   DCHECK(worker_.get());
55
56   worker_->SetNewOwner(new_owner);
57   return worker_.release();
58 }
59
60 base::MessageLoop* PrinterQuery::message_loop() {
61   return io_message_loop_;
62 }
63
64 const PrintSettings& PrinterQuery::settings() const {
65   return settings_;
66 }
67
68 int PrinterQuery::cookie() const {
69   return cookie_;
70 }
71
72 void PrinterQuery::GetSettings(
73     GetSettingsAskParam ask_user_for_settings,
74     scoped_ptr<PrintingUIWebContentsObserver> web_contents_observer,
75     int expected_page_count,
76     bool has_selection,
77     MarginType margin_type,
78     const base::Closure& callback) {
79   DCHECK_EQ(io_message_loop_, base::MessageLoop::current());
80   DCHECK(!is_print_dialog_box_shown_);
81
82   StartWorker(callback);
83
84   // Real work is done in PrintJobWorker::GetSettings().
85   is_print_dialog_box_shown_ = ask_user_for_settings == ASK_USER;
86   worker_->message_loop()->PostTask(
87       FROM_HERE,
88       base::Bind(&PrintJobWorker::GetSettings,
89                  base::Unretained(worker_.get()),
90                  is_print_dialog_box_shown_,
91                  base::Passed(&web_contents_observer),
92                  expected_page_count,
93                  has_selection,
94                  margin_type));
95 }
96
97 void PrinterQuery::SetSettings(const base::DictionaryValue& new_settings,
98                                const base::Closure& callback) {
99   StartWorker(callback);
100
101   worker_->message_loop()->PostTask(
102       FROM_HERE,
103       base::Bind(&PrintJobWorker::SetSettings,
104                  base::Unretained(worker_.get()),
105                  new_settings.DeepCopy()));
106 }
107
108 void PrinterQuery::SetWorkerDestination(
109     PrintDestinationInterface* destination) {
110   worker_->SetPrintDestination(destination);
111 }
112
113 void PrinterQuery::StartWorker(const base::Closure& callback) {
114   DCHECK(callback_.is_null());
115   DCHECK(worker_.get());
116
117   // Lazily create the worker thread. There is one worker thread per print job.
118   if (!worker_->message_loop())
119     worker_->Start();
120
121   callback_ = callback;
122 }
123
124 void PrinterQuery::StopWorker() {
125   if (worker_.get()) {
126     // http://crbug.com/66082: We're blocking on the PrinterQuery's worker
127     // thread.  It's not clear to me if this may result in blocking the current
128     // thread for an unacceptable time.  We should probably fix it.
129     base::ThreadRestrictions::ScopedAllowIO allow_io;
130     worker_->Stop();
131     worker_.reset();
132   }
133 }
134
135 bool PrinterQuery::is_callback_pending() const {
136   return !callback_.is_null();
137 }
138
139 bool PrinterQuery::is_valid() const {
140   return worker_.get() != NULL;
141 }
142
143 }  // namespace printing