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 #ifndef CHROME_SERVICE_CLOUD_PRINT_PRINTER_JOB_HANDLER_H_
6 #define CHROME_SERVICE_CLOUD_PRINT_PRINTER_JOB_HANDLER_H_
12 #include "base/files/file_path.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/single_thread_task_runner.h"
16 #include "base/threading/thread.h"
17 #include "base/time/time.h"
18 #include "chrome/service/cloud_print/cloud_print_url_fetcher.h"
19 #include "chrome/service/cloud_print/job_status_updater.h"
20 #include "chrome/service/cloud_print/printer_job_queue_handler.h"
21 #include "net/url_request/url_request_status.h"
22 #include "printing/backend/print_backend.h"
26 // A class that handles cloud print jobs for a particular printer. This class
27 // imlements a state machine that transitions from Start to various states. The
28 // various states are shown in the below diagram.
29 // the status on the server.
31 // Start --> No pending tasks --> Done
34 // | Have Pending tasks
37 // | ---Update Pending----->
41 // | Update Printer info on server
47 // Fetch Next Job Metadata
51 // Create Job StatusUpdater for job
52 // Mark job as "in progress" on server
53 // (On any unrecoverable error in any of the above steps go to Stop)
63 // (If there are pending tasks go back to Start)
65 namespace cloud_print
{
67 class PrinterJobHandler
: public base::RefCountedThreadSafe
<PrinterJobHandler
>,
68 public CloudPrintURLFetcherDelegate
,
69 public JobStatusUpdaterDelegate
,
70 public PrintSystem::PrinterWatcher::Delegate
,
71 public PrintSystem::JobSpooler::Delegate
{
75 // Notify delegate about authentication error.
76 virtual void OnAuthError() = 0;
77 // Notify delegate that printer has been deleted.
78 virtual void OnPrinterDeleted(const std::string
& printer_name
) = 0;
81 virtual ~Delegate() {}
84 struct PrinterInfoFromCloud
{
85 std::string printer_id
;
86 std::string caps_hash
;
87 std::string tags_hash
;
88 int current_xmpp_timeout
;
89 int pending_xmpp_timeout
;
91 PrinterInfoFromCloud();
94 // Begin public interface
95 PrinterJobHandler(const printing::PrinterBasicInfo
& printer_info
,
96 const PrinterInfoFromCloud
& printer_info_from_server
,
97 const GURL
& cloud_print_server_url
,
98 PrintSystem
* print_system
,
103 std::string
GetPrinterName() const;
105 // Requests a job check. |reason| is the reason for fetching the job. Used
106 // for logging and diagnostc purposes.
107 void CheckForJobs(const std::string
& reason
);
109 // Shutdown everything (the process is exiting).
112 base::TimeTicks
last_job_fetch_time() const { return last_job_fetch_time_
; }
113 // End public interface
115 // Begin Delegate implementations
117 // CloudPrintURLFetcher::Delegate implementation.
118 CloudPrintURLFetcher::ResponseAction
HandleRawResponse(
119 const net::URLFetcher
* source
,
121 const net::URLRequestStatus
& status
,
123 const net::ResponseCookies
& cookies
,
124 const std::string
& data
) override
;
125 CloudPrintURLFetcher::ResponseAction
HandleRawData(
126 const net::URLFetcher
* source
,
128 const std::string
& data
) override
;
129 CloudPrintURLFetcher::ResponseAction
HandleJSONData(
130 const net::URLFetcher
* source
,
132 base::DictionaryValue
* json_data
,
133 bool succeeded
) override
;
134 void OnRequestGiveUp() override
;
135 CloudPrintURLFetcher::ResponseAction
OnRequestAuthError() override
;
136 std::string
GetAuthHeader() override
;
138 // JobStatusUpdater::Delegate implementation
139 bool OnJobCompleted(JobStatusUpdater
* updater
) override
;
140 void OnAuthError() override
;
142 // PrinterWatcherDelegate implementation
143 void OnPrinterDeleted() override
;
144 void OnPrinterChanged() override
;
145 void OnJobChanged() override
;
147 // JobSpoolerDelegate implementation.
148 // Called on print_thread_.
149 void OnJobSpoolSucceeded(const PlatformJobId
& job_id
) override
;
150 void OnJobSpoolFailed() override
;
152 // End Delegate implementations
154 static void ReportsStats();
157 friend class base::RefCountedThreadSafe
<PrinterJobHandler
>;
162 JOB_VALIDATE_TICKET_FAILED
,
167 // Prototype for a JSON data handler.
168 typedef CloudPrintURLFetcher::ResponseAction
169 (PrinterJobHandler::*JSONDataHandler
)(const net::URLFetcher
* source
,
171 base::DictionaryValue
* json_data
,
173 // Prototype for a data handler.
174 typedef CloudPrintURLFetcher::ResponseAction
175 (PrinterJobHandler::*DataHandler
)(const net::URLFetcher
* source
,
177 const std::string
& data
);
179 ~PrinterJobHandler() override
;
181 // Begin request handlers for each state in the state machine
182 CloudPrintURLFetcher::ResponseAction
HandlePrinterUpdateResponse(
183 const net::URLFetcher
* source
,
185 base::DictionaryValue
* json_data
,
188 CloudPrintURLFetcher::ResponseAction
HandleJobMetadataResponse(
189 const net::URLFetcher
* source
,
191 base::DictionaryValue
* json_data
,
194 CloudPrintURLFetcher::ResponseAction
HandlePrintTicketResponse(
195 const net::URLFetcher
* source
,
197 const std::string
& data
);
199 CloudPrintURLFetcher::ResponseAction
HandlePrintDataResponse(
200 const net::URLFetcher
* source
,
202 const std::string
& data
);
204 CloudPrintURLFetcher::ResponseAction
HandleInProgressStatusUpdateResponse(
205 const net::URLFetcher
* source
,
207 base::DictionaryValue
* json_data
,
210 CloudPrintURLFetcher::ResponseAction
HandleFailureStatusUpdateResponse(
211 const net::URLFetcher
* source
,
213 base::DictionaryValue
* json_data
,
215 // End request handlers for each state in the state machine
217 // Start the state machine. Based on the flags set this could mean updating
218 // printer information, deleting the printer from the server or looking for
222 // End the state machine. If there are pending tasks, we will post a Start
226 void StartPrinting();
228 void UpdateJobStatus(PrintJobStatus status
, PrintJobError error
);
230 // Run a job check as the result of a scheduled check
231 void RunScheduledJobCheck();
233 // Sets the next response handler to the specified JSON data handler.
234 void SetNextJSONHandler(JSONDataHandler handler
);
235 // Sets the next response handler to the specified data handler.
236 void SetNextDataHandler(DataHandler handler
);
238 void JobFailed(PrintJobError error
);
239 void JobSpooled(PlatformJobId local_job_id
);
240 // Returns false if printer info is up to date and no updating is needed.
241 bool UpdatePrinterInfo();
242 bool HavePendingTasks();
243 void ValidatePrintTicketFailed();
245 // Callback that asynchronously receives printer caps and defaults.
246 void OnReceivePrinterCaps(
248 const std::string
& printer_name
,
249 const printing::PrinterCapsAndDefaults
& caps_and_defaults
);
251 // Called on print_thread_.
252 void DoPrint(const JobDetails
& job_details
,
253 const std::string
& printer_name
);
255 scoped_refptr
<CloudPrintURLFetcher
> request_
;
256 scoped_refptr
<PrintSystem
> print_system_
;
257 printing::PrinterBasicInfo printer_info_
;
258 PrinterInfoFromCloud printer_info_cloud_
;
259 GURL cloud_print_server_url_
;
260 std::string print_data_url_
;
261 JobDetails job_details_
;
263 // Once the job has been spooled to the local spooler, this specifies the
264 // job id of the job on the local spooler.
265 PlatformJobId local_job_id_
;
267 // The next response handler can either be a JSONDataHandler or a
268 // DataHandler (depending on the current request being made).
269 JSONDataHandler next_json_data_handler_
;
270 DataHandler next_data_handler_
;
271 // The thread on which the actual print operation happens
272 base::Thread print_thread_
;
273 // The Job spooler object. This is only non-NULL during a print operation.
274 // It lives and dies on |print_thread_|
275 scoped_refptr
<PrintSystem::JobSpooler
> job_spooler_
;
276 // The message loop proxy representing the thread on which this object
277 // was created. Used by the print thread.
278 scoped_refptr
<base::SingleThreadTaskRunner
> job_handler_task_runner_
;
280 // There may be pending tasks in the message queue when Shutdown is called.
281 // We set this flag so as to do nothing in those tasks.
284 // A string indicating the reason we are fetching jobs from the server
285 // (used to specify the reason in the fetch URL).
286 std::string job_fetch_reason_
;
287 // Flags that specify various pending server updates
288 bool job_check_pending_
;
289 bool printer_update_pending_
;
291 // Some task in the state machine is in progress.
292 bool task_in_progress_
;
293 scoped_refptr
<PrintSystem::PrinterWatcher
> printer_watcher_
;
294 typedef std::list
< scoped_refptr
<JobStatusUpdater
> > JobStatusUpdaterList
;
295 JobStatusUpdaterList job_status_updater_list_
;
297 // Manages parsing the job queue
298 PrinterJobQueueHandler job_queue_handler_
;
300 base::TimeTicks last_job_fetch_time_
;
302 base::Time job_start_time_
;
303 base::Time spooling_start_time_
;
304 base::Time last_caps_update_time_
;
306 base::WeakPtrFactory
<PrinterJobHandler
> weak_ptr_factory_
;
308 DISALLOW_COPY_AND_ASSIGN(PrinterJobHandler
);
311 // This typedef is to workaround the issue with certain versions of
312 // Visual Studio where it gets confused between multiple Delegate
313 // classes and gives a C2500 error. (I saw this error on the try bots -
314 // the workaround was not needed for my machine).
315 typedef PrinterJobHandler::Delegate PrinterJobHandlerDelegate
;
317 } // namespace cloud_print
319 #endif // CHROME_SERVICE_CLOUD_PRINT_PRINTER_JOB_HANDLER_H_