6cd11ff067ef9537b1c6ee0131160c8eb8805b1d
[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
14 namespace printing {
15
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());
22 }
23
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());
29 }
30
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();
38   } else {
39     // Failure.
40     cookie_ = 0;
41   }
42
43   if (!callback_.is_null()) {
44     // This may cause reentrancy like to call StopWorker().
45     callback_.Run();
46     callback_.Reset();
47   }
48 }
49
50 PrintJobWorker* PrinterQuery::DetachWorker(PrintJobWorkerOwner* new_owner) {
51   DCHECK(callback_.is_null());
52   DCHECK(worker_.get());
53
54   worker_->SetNewOwner(new_owner);
55   return worker_.release();
56 }
57
58 const PrintSettings& PrinterQuery::settings() const {
59   return settings_;
60 }
61
62 int PrinterQuery::cookie() const {
63   return cookie_;
64 }
65
66 void PrinterQuery::GetSettings(
67     GetSettingsAskParam ask_user_for_settings,
68     int expected_page_count,
69     bool has_selection,
70     MarginType margin_type,
71     const base::Closure& callback) {
72   DCHECK(RunsTasksOnCurrentThread());
73   DCHECK(!is_print_dialog_box_shown_);
74
75   StartWorker(callback);
76
77   // Real work is done in PrintJobWorker::GetSettings().
78   is_print_dialog_box_shown_ = ask_user_for_settings == ASK_USER;
79   worker_->PostTask(FROM_HERE,
80                     base::Bind(&PrintJobWorker::GetSettings,
81                                base::Unretained(worker_.get()),
82                                is_print_dialog_box_shown_,
83                                expected_page_count,
84                                has_selection,
85                                margin_type));
86 }
87
88 void PrinterQuery::SetSettings(scoped_ptr<base::DictionaryValue> new_settings,
89                                const base::Closure& callback) {
90   StartWorker(callback);
91
92   worker_->PostTask(FROM_HERE,
93                     base::Bind(&PrintJobWorker::SetSettings,
94                                base::Unretained(worker_.get()),
95                                base::Passed(&new_settings)));
96 }
97
98 void PrinterQuery::StartWorker(const base::Closure& callback) {
99   DCHECK(callback_.is_null());
100   DCHECK(worker_.get());
101
102   // Lazily create the worker thread. There is one worker thread per print job.
103   if (!worker_->IsRunning())
104     worker_->Start();
105
106   callback_ = callback;
107 }
108
109 void PrinterQuery::StopWorker() {
110   if (worker_.get()) {
111     // http://crbug.com/66082: We're blocking on the PrinterQuery's worker
112     // thread.  It's not clear to me if this may result in blocking the current
113     // thread for an unacceptable time.  We should probably fix it.
114     base::ThreadRestrictions::ScopedAllowIO allow_io;
115     worker_->Stop();
116     worker_.reset();
117   }
118 }
119
120 bool PrinterQuery::is_callback_pending() const {
121   return !callback_.is_null();
122 }
123
124 bool PrinterQuery::is_valid() const {
125   return worker_.get() != NULL;
126 }
127
128 }  // namespace printing