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

Side by Side Diff: chrome/service/cloud_print/printer_job_handler.cc

Issue 10065040: RefCounted types should not have public destructors, chrome/ remaining parts (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Implementation fixes Created 8 years, 8 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
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/service/cloud_print/printer_job_handler.h" 5 #include "chrome/service/cloud_print/printer_job_handler.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/file_util.h" 9 #include "base/file_util.h"
10 #include "base/json/json_reader.h" 10 #include "base/json/json_reader.h"
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 if (!print_system_->IsValidPrinter(printer_info_.printer_name)) 62 if (!print_system_->IsValidPrinter(printer_info_.printer_name))
63 return false; 63 return false;
64 64
65 printer_watcher_ = print_system_->CreatePrinterWatcher( 65 printer_watcher_ = print_system_->CreatePrinterWatcher(
66 printer_info_.printer_name); 66 printer_info_.printer_name);
67 printer_watcher_->StartWatching(this); 67 printer_watcher_->StartWatching(this);
68 CheckForJobs(kJobFetchReasonStartup); 68 CheckForJobs(kJobFetchReasonStartup);
69 return true; 69 return true;
70 } 70 }
71 71
72 PrinterJobHandler::~PrinterJobHandler() {
73 if (printer_watcher_)
74 printer_watcher_->StopWatching();
75 }
76
77 void PrinterJobHandler::Reset() {
78 print_data_url_.clear();
79 job_details_.Clear();
80 request_ = NULL;
81 print_thread_.Stop();
82 }
83
84 std::string PrinterJobHandler::GetPrinterName() const { 72 std::string PrinterJobHandler::GetPrinterName() const {
85 return printer_info_.printer_name; 73 return printer_info_.printer_name;
86 } 74 }
87 75
88 void PrinterJobHandler::Start() {
89 VLOG(1) << "CP_CONNECTOR: Start printer job handler, id: "
90 << printer_info_cloud_.printer_id
91 << ", task in progress: " << task_in_progress_;
92 if (task_in_progress_) {
93 // Multiple Starts can get posted because of multiple notifications
94 // We want to ignore the other ones that happen when a task is in progress.
95 return;
96 }
97 Reset();
98 if (!shutting_down_) {
99 // Check if we have work to do.
100 if (HavePendingTasks()) {
101 if (!task_in_progress_ && printer_update_pending_) {
102 printer_update_pending_ = false;
103 task_in_progress_ = UpdatePrinterInfo();
104 }
105 if (!task_in_progress_ && job_check_pending_) {
106 task_in_progress_ = true;
107 job_check_pending_ = false;
108 // We need to fetch any pending jobs for this printer
109 SetNextJSONHandler(&PrinterJobHandler::HandleJobMetadataResponse);
110 request_ = new CloudPrintURLFetcher;
111 request_->StartGetRequest(
112 CloudPrintHelpers::GetUrlForJobFetch(
113 cloud_print_server_url_, printer_info_cloud_.printer_id,
114 job_fetch_reason_),
115 this,
116 kCloudPrintAPIMaxRetryCount,
117 std::string());
118 last_job_fetch_time_ = base::TimeTicks::Now();
119 VLOG(1) << "Last job fetch time for printer "
120 << printer_info_.printer_name.c_str() << " is "
121 << last_job_fetch_time_.ToInternalValue();
122 job_fetch_reason_.clear();
123 }
124 }
125 }
126 }
127
128 void PrinterJobHandler::Stop() {
129 VLOG(1) << "CP_CONNECTOR: Stop printer job handler, id: "
130 << printer_info_cloud_.printer_id;
131 task_in_progress_ = false;
132 Reset();
133 if (HavePendingTasks()) {
134 MessageLoop::current()->PostTask(
135 FROM_HERE, base::Bind(&PrinterJobHandler::Start, this));
136 }
137 }
138
139 void PrinterJobHandler::CheckForJobs(const std::string& reason) { 76 void PrinterJobHandler::CheckForJobs(const std::string& reason) {
140 VLOG(1) << "CP_CONNECTOR: CheckForJobs, id: " 77 VLOG(1) << "CP_CONNECTOR: CheckForJobs, id: "
141 << printer_info_cloud_.printer_id 78 << printer_info_cloud_.printer_id
142 << ", reason: " << reason 79 << ", reason: " << reason
143 << ", task in progress: " << task_in_progress_; 80 << ", task in progress: " << task_in_progress_;
144 job_fetch_reason_ = reason; 81 job_fetch_reason_ = reason;
145 job_check_pending_ = true; 82 job_check_pending_ = true;
146 if (!task_in_progress_) { 83 if (!task_in_progress_) {
147 MessageLoop::current()->PostTask( 84 MessageLoop::current()->PostTask(
148 FROM_HERE, base::Bind(&PrinterJobHandler::Start, this)); 85 FROM_HERE, base::Bind(&PrinterJobHandler::Start, this));
149 } 86 }
150 } 87 }
151 88
152 bool PrinterJobHandler::UpdatePrinterInfo() { 89 void PrinterJobHandler::Shutdown() {
153 if (!printer_watcher_) { 90 VLOG(1) << "CP_CONNECTOR: Printer job handler shutdown, id: "
154 LOG(ERROR) << "CP_CONNECTOR: Printer watcher is missing."
155 << "Check printer server url for printer id: "
156 << printer_info_cloud_.printer_id;
157 return false;
158 }
159
160 VLOG(1) << "CP_CONNECTOR: Update printer info, id: "
161 << printer_info_cloud_.printer_id; 91 << printer_info_cloud_.printer_id;
162 // We need to update the parts of the printer info that have changed 92 Reset();
163 // (could be printer name, description, status or capabilities). 93 shutting_down_ = true;
164 // First asynchronously fetch the capabilities. 94 while (!job_status_updater_list_.empty()) {
165 printing::PrinterBasicInfo printer_info; 95 // Calling Stop() will cause the OnJobCompleted to be called which will
166 printer_watcher_->GetCurrentPrinterInfo(&printer_info); 96 // remove the updater object from the list.
167 97 job_status_updater_list_.front()->Stop();
168 // Asynchronously fetch the printer caps and defaults. The story will
169 // continue in OnReceivePrinterCaps.
170 print_system_->GetPrinterCapsAndDefaults(
171 printer_info.printer_name.c_str(),
172 base::Bind(&PrinterJobHandler::OnReceivePrinterCaps,
173 weak_ptr_factory_.GetWeakPtr()));
174
175 // While we are waiting for the data, pretend we have work to do and return
176 // true.
177 return true;
178 }
179
180 void PrinterJobHandler::OnReceivePrinterCaps(
181 bool succeeded,
182 const std::string& printer_name,
183 const printing::PrinterCapsAndDefaults& caps_and_defaults) {
184 printing::PrinterBasicInfo printer_info;
185 if (printer_watcher_)
186 printer_watcher_->GetCurrentPrinterInfo(&printer_info);
187
188 std::string post_data;
189 std::string mime_boundary;
190 cloud_print::CreateMimeBoundaryForUpload(&mime_boundary);
191
192 if (succeeded) {
193 std::string caps_hash =
194 base::MD5String(caps_and_defaults.printer_capabilities);
195 if (caps_hash != printer_info_cloud_.caps_hash) {
196 // Hashes don't match, we need to upload new capabilities (the defaults
197 // go for free along with the capabilities)
198 printer_info_cloud_.caps_hash = caps_hash;
199 cloud_print::AddMultipartValueForUpload(kPrinterCapsValue,
200 caps_and_defaults.printer_capabilities, mime_boundary,
201 caps_and_defaults.caps_mime_type, &post_data);
202 cloud_print::AddMultipartValueForUpload(kPrinterDefaultsValue,
203 caps_and_defaults.printer_defaults, mime_boundary,
204 caps_and_defaults.defaults_mime_type, &post_data);
205 cloud_print::AddMultipartValueForUpload(kPrinterCapsHashValue,
206 caps_hash, mime_boundary, std::string(), &post_data);
207 }
208 } else {
209 LOG(ERROR) << "Failed to get printer caps and defaults for printer: "
210 << printer_name;
211 }
212
213 std::string tags_hash =
214 CloudPrintHelpers::GenerateHashOfStringMap(printer_info.options);
215 if (tags_hash != printer_info_cloud_.tags_hash) {
216 printer_info_cloud_.tags_hash = tags_hash;
217 CloudPrintHelpers::GenerateMultipartPostDataForPrinterTags(
218 printer_info.options, mime_boundary, &post_data);
219 // Remove all the exising proxy tags.
220 std::string cp_tag_wildcard(kProxyTagPrefix);
221 cp_tag_wildcard += ".*";
222 cloud_print::AddMultipartValueForUpload(kPrinterRemoveTagValue,
223 cp_tag_wildcard, mime_boundary, std::string(), &post_data);
224 }
225
226 if (printer_info.printer_name != printer_info_.printer_name) {
227 cloud_print::AddMultipartValueForUpload(kPrinterNameValue,
228 printer_info.printer_name, mime_boundary, std::string(), &post_data);
229 }
230 if (printer_info.printer_description != printer_info_.printer_description) {
231 cloud_print::AddMultipartValueForUpload(kPrinterDescValue,
232 printer_info.printer_description, mime_boundary,
233 std::string(), &post_data);
234 }
235 if (printer_info.printer_status != printer_info_.printer_status) {
236 cloud_print::AddMultipartValueForUpload(kPrinterStatusValue,
237 base::StringPrintf("%d", printer_info.printer_status), mime_boundary,
238 std::string(), &post_data);
239 }
240 printer_info_ = printer_info;
241 if (!post_data.empty()) {
242 // Terminate the request body
243 post_data.append("--" + mime_boundary + "--\r\n");
244 std::string mime_type("multipart/form-data; boundary=");
245 mime_type += mime_boundary;
246 SetNextJSONHandler(&PrinterJobHandler::HandlePrinterUpdateResponse);
247 request_ = new CloudPrintURLFetcher;
248 request_->StartPostRequest(
249 CloudPrintHelpers::GetUrlForPrinterUpdate(
250 cloud_print_server_url_, printer_info_cloud_.printer_id),
251 this,
252 kCloudPrintAPIMaxRetryCount,
253 mime_type,
254 post_data,
255 std::string());
256 } else {
257 // We are done here. Go to the Stop state
258 MessageLoop::current()->PostTask(
259 FROM_HERE, base::Bind(&PrinterJobHandler::Stop, this));
260 } 98 }
261 } 99 }
262 100
263 // CloudPrintURLFetcher::Delegate implementation. 101 // CloudPrintURLFetcher::Delegate implementation.
264 CloudPrintURLFetcher::ResponseAction PrinterJobHandler::HandleRawResponse( 102 CloudPrintURLFetcher::ResponseAction PrinterJobHandler::HandleRawResponse(
265 const content::URLFetcher* source, 103 const content::URLFetcher* source,
266 const GURL& url, 104 const GURL& url,
267 const net::URLRequestStatus& status, 105 const net::URLRequestStatus& status,
268 int response_code, 106 int response_code,
269 const net::ResponseCookies& cookies, 107 const net::ResponseCookies& cookies,
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 void PrinterJobHandler::OnJobChanged() { 194 void PrinterJobHandler::OnJobChanged() {
357 // Some job on the printer changed. Loop through all our JobStatusUpdaters 195 // Some job on the printer changed. Loop through all our JobStatusUpdaters
358 // and have them check for updates. 196 // and have them check for updates.
359 for (JobStatusUpdaterList::iterator index = job_status_updater_list_.begin(); 197 for (JobStatusUpdaterList::iterator index = job_status_updater_list_.begin();
360 index != job_status_updater_list_.end(); index++) { 198 index != job_status_updater_list_.end(); index++) {
361 MessageLoop::current()->PostTask( 199 MessageLoop::current()->PostTask(
362 FROM_HERE, base::Bind(&JobStatusUpdater::UpdateStatus, index->get())); 200 FROM_HERE, base::Bind(&JobStatusUpdater::UpdateStatus, index->get()));
363 } 201 }
364 } 202 }
365 203
204 void PrinterJobHandler::OnJobSpoolSucceeded(
205 const cloud_print::PlatformJobId& job_id) {
206 DCHECK(MessageLoop::current() == print_thread_.message_loop());
207 job_spooler_ = NULL;
208 job_handler_message_loop_proxy_->PostTask(
209 FROM_HERE, base::Bind(&PrinterJobHandler::JobSpooled, this, job_id));
210 }
211
212 void PrinterJobHandler::OnJobSpoolFailed() {
213 DCHECK(MessageLoop::current() == print_thread_.message_loop());
214 job_spooler_ = NULL;
215 job_handler_message_loop_proxy_->PostTask(
216 FROM_HERE, base::Bind(&PrinterJobHandler::JobFailed, this, PRINT_FAILED));
217 }
218
219 PrinterJobHandler::~PrinterJobHandler() {
220 if (printer_watcher_)
221 printer_watcher_->StopWatching();
222 }
223
366 // Begin Response handlers 224 // Begin Response handlers
367 CloudPrintURLFetcher::ResponseAction 225 CloudPrintURLFetcher::ResponseAction
368 PrinterJobHandler::HandlePrinterUpdateResponse( 226 PrinterJobHandler::HandlePrinterUpdateResponse(
369 const content::URLFetcher* source, 227 const content::URLFetcher* source,
370 const GURL& url, 228 const GURL& url,
371 DictionaryValue* json_data, 229 DictionaryValue* json_data,
372 bool succeeded) { 230 bool succeeded) {
373 VLOG(1) << "CP_CONNECTOR: Handle printer update response, id: " 231 VLOG(1) << "CP_CONNECTOR: Handle printer update response, id: "
374 << printer_info_cloud_.printer_id; 232 << printer_info_cloud_.printer_id;
375 // We are done here. Go to the Stop state 233 // We are done here. Go to the Stop state
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 const content::URLFetcher* source, 368 const content::URLFetcher* source,
511 const GURL& url, 369 const GURL& url,
512 DictionaryValue* json_data, 370 DictionaryValue* json_data,
513 bool succeeded) { 371 bool succeeded) {
514 VLOG(1) << "CP_CONNECTOR: Handle failure status update response, id: " 372 VLOG(1) << "CP_CONNECTOR: Handle failure status update response, id: "
515 << printer_info_cloud_.printer_id; 373 << printer_info_cloud_.printer_id;
516 MessageLoop::current()->PostTask( 374 MessageLoop::current()->PostTask(
517 FROM_HERE, base::Bind(&PrinterJobHandler::Stop, this)); 375 FROM_HERE, base::Bind(&PrinterJobHandler::Stop, this));
518 return CloudPrintURLFetcher::STOP_PROCESSING; 376 return CloudPrintURLFetcher::STOP_PROCESSING;
519 } 377 }
520 // End Response handlers 378
379 void PrinterJobHandler::Start() {
380 VLOG(1) << "CP_CONNECTOR: Start printer job handler, id: "
381 << printer_info_cloud_.printer_id
382 << ", task in progress: " << task_in_progress_;
383 if (task_in_progress_) {
384 // Multiple Starts can get posted because of multiple notifications
385 // We want to ignore the other ones that happen when a task is in progress.
386 return;
387 }
388 Reset();
389 if (!shutting_down_) {
390 // Check if we have work to do.
391 if (HavePendingTasks()) {
392 if (!task_in_progress_ && printer_update_pending_) {
393 printer_update_pending_ = false;
394 task_in_progress_ = UpdatePrinterInfo();
395 }
396 if (!task_in_progress_ && job_check_pending_) {
397 task_in_progress_ = true;
398 job_check_pending_ = false;
399 // We need to fetch any pending jobs for this printer
400 SetNextJSONHandler(&PrinterJobHandler::HandleJobMetadataResponse);
401 request_ = new CloudPrintURLFetcher;
402 request_->StartGetRequest(
403 CloudPrintHelpers::GetUrlForJobFetch(
404 cloud_print_server_url_, printer_info_cloud_.printer_id,
405 job_fetch_reason_),
406 this,
407 kCloudPrintAPIMaxRetryCount,
408 std::string());
409 last_job_fetch_time_ = base::TimeTicks::Now();
410 VLOG(1) << "Last job fetch time for printer "
411 << printer_info_.printer_name.c_str() << " is "
412 << last_job_fetch_time_.ToInternalValue();
413 job_fetch_reason_.clear();
414 }
415 }
416 }
417 }
418
419 void PrinterJobHandler::Stop() {
420 VLOG(1) << "CP_CONNECTOR: Stop printer job handler, id: "
421 << printer_info_cloud_.printer_id;
422 task_in_progress_ = false;
423 Reset();
424 if (HavePendingTasks()) {
425 MessageLoop::current()->PostTask(
426 FROM_HERE, base::Bind(&PrinterJobHandler::Start, this));
427 }
428 }
521 429
522 void PrinterJobHandler::StartPrinting() { 430 void PrinterJobHandler::StartPrinting() {
523 VLOG(1) << "CP_CONNECTOR: Start printing, id: " 431 VLOG(1) << "CP_CONNECTOR: Start printing, id: "
524 << printer_info_cloud_.printer_id; 432 << printer_info_cloud_.printer_id;
525 // We are done with the request object for now. 433 // We are done with the request object for now.
526 request_ = NULL; 434 request_ = NULL;
527 if (!shutting_down_) { 435 if (!shutting_down_) {
528 if (!print_thread_.Start()) { 436 if (!print_thread_.Start()) {
529 JobFailed(PRINT_FAILED); 437 JobFailed(PRINT_FAILED);
530 } else { 438 } else {
531 print_thread_.message_loop()->PostTask( 439 print_thread_.message_loop()->PostTask(
532 FROM_HERE, base::Bind(&PrinterJobHandler::DoPrint, this, job_details_, 440 FROM_HERE, base::Bind(&PrinterJobHandler::DoPrint, this, job_details_,
533 printer_info_.printer_name)); 441 printer_info_.printer_name));
534 } 442 }
535 } 443 }
536 } 444 }
537 445
538 void PrinterJobHandler::JobFailed(PrintJobError error) { 446 void PrinterJobHandler::Reset() {
539 VLOG(1) << "CP_CONNECTOR: Job failed, id: " << printer_info_cloud_.printer_id; 447 print_data_url_.clear();
540 if (!shutting_down_) { 448 job_details_.Clear();
541 UpdateJobStatus(cloud_print::PRINT_JOB_STATUS_ERROR, error); 449 request_ = NULL;
542 } 450 print_thread_.Stop();
543 }
544
545 void PrinterJobHandler::JobSpooled(cloud_print::PlatformJobId local_job_id) {
546 VLOG(1) << "CP_CONNECTOR: Job spooled, printer id: "
547 << printer_info_cloud_.printer_id << ", job id: " << local_job_id;
548 if (!shutting_down_) {
549 local_job_id_ = local_job_id;
550 UpdateJobStatus(cloud_print::PRINT_JOB_STATUS_IN_PROGRESS, SUCCESS);
551 print_thread_.Stop();
552 }
553 }
554
555 void PrinterJobHandler::Shutdown() {
556 VLOG(1) << "CP_CONNECTOR: Printer job handler shutdown, id: "
557 << printer_info_cloud_.printer_id;
558 Reset();
559 shutting_down_ = true;
560 while (!job_status_updater_list_.empty()) {
561 // Calling Stop() will cause the OnJobCompleted to be called which will
562 // remove the updater object from the list.
563 job_status_updater_list_.front()->Stop();
564 }
565 } 451 }
566 452
567 void PrinterJobHandler::UpdateJobStatus(cloud_print::PrintJobStatus status, 453 void PrinterJobHandler::UpdateJobStatus(cloud_print::PrintJobStatus status,
568 PrintJobError error) { 454 PrintJobError error) {
569 VLOG(1) << "CP_CONNECTOR: Update job status, id: " 455 VLOG(1) << "CP_CONNECTOR: Update job status, id: "
570 << printer_info_cloud_.printer_id; 456 << printer_info_cloud_.printer_id;
571 if (!shutting_down_) { 457 if (!shutting_down_) {
572 if (!job_details_.job_id_.empty()) { 458 if (!job_details_.job_id_.empty()) {
573 VLOG(1) << "CP_CONNECTOR: Updating status, job id: " 459 VLOG(1) << "CP_CONNECTOR: Updating status, job id: "
574 << job_details_.job_id_ << ", status: " << status; 460 << job_details_.job_id_ << ", status: " << status;
(...skipping 19 matching lines...) Expand all
594 void PrinterJobHandler::SetNextJSONHandler(JSONDataHandler handler) { 480 void PrinterJobHandler::SetNextJSONHandler(JSONDataHandler handler) {
595 next_json_data_handler_ = handler; 481 next_json_data_handler_ = handler;
596 next_data_handler_ = NULL; 482 next_data_handler_ = NULL;
597 } 483 }
598 484
599 void PrinterJobHandler::SetNextDataHandler(DataHandler handler) { 485 void PrinterJobHandler::SetNextDataHandler(DataHandler handler) {
600 next_data_handler_ = handler; 486 next_data_handler_ = handler;
601 next_json_data_handler_ = NULL; 487 next_json_data_handler_ = NULL;
602 } 488 }
603 489
490 void PrinterJobHandler::JobFailed(PrintJobError error) {
491 VLOG(1) << "CP_CONNECTOR: Job failed, id: " << printer_info_cloud_.printer_id;
492 if (!shutting_down_) {
493 UpdateJobStatus(cloud_print::PRINT_JOB_STATUS_ERROR, error);
494 }
495 }
496
497 void PrinterJobHandler::JobSpooled(cloud_print::PlatformJobId local_job_id) {
498 VLOG(1) << "CP_CONNECTOR: Job spooled, printer id: "
499 << printer_info_cloud_.printer_id << ", job id: " << local_job_id;
500 if (!shutting_down_) {
501 local_job_id_ = local_job_id;
502 UpdateJobStatus(cloud_print::PRINT_JOB_STATUS_IN_PROGRESS, SUCCESS);
503 print_thread_.Stop();
504 }
505 }
506
507 bool PrinterJobHandler::UpdatePrinterInfo() {
508 if (!printer_watcher_) {
509 LOG(ERROR) << "CP_CONNECTOR: Printer watcher is missing."
510 << "Check printer server url for printer id: "
511 << printer_info_cloud_.printer_id;
512 return false;
513 }
514
515 VLOG(1) << "CP_CONNECTOR: Update printer info, id: "
516 << printer_info_cloud_.printer_id;
517 // We need to update the parts of the printer info that have changed
518 // (could be printer name, description, status or capabilities).
519 // First asynchronously fetch the capabilities.
520 printing::PrinterBasicInfo printer_info;
521 printer_watcher_->GetCurrentPrinterInfo(&printer_info);
522
523 // Asynchronously fetch the printer caps and defaults. The story will
524 // continue in OnReceivePrinterCaps.
525 print_system_->GetPrinterCapsAndDefaults(
526 printer_info.printer_name.c_str(),
527 base::Bind(&PrinterJobHandler::OnReceivePrinterCaps,
528 weak_ptr_factory_.GetWeakPtr()));
529
530 // While we are waiting for the data, pretend we have work to do and return
531 // true.
532 return true;
533 }
534
604 bool PrinterJobHandler::HavePendingTasks() { 535 bool PrinterJobHandler::HavePendingTasks() {
605 return (job_check_pending_ || printer_update_pending_); 536 return (job_check_pending_ || printer_update_pending_);
606 } 537 }
607 538
608 void PrinterJobHandler::FailedFetchingJobData() { 539 void PrinterJobHandler::FailedFetchingJobData() {
609 if (!shutting_down_) { 540 if (!shutting_down_) {
610 LOG(ERROR) << "CP_CONNECTOR: Failed fetching job data for printer: " << 541 LOG(ERROR) << "CP_CONNECTOR: Failed fetching job data for printer: " <<
611 printer_info_.printer_name << ", job id: " << job_details_.job_id_; 542 printer_info_.printer_name << ", job id: " << job_details_.job_id_;
612 JobFailed(INVALID_JOB_DATA); 543 JobFailed(INVALID_JOB_DATA);
613 } 544 }
614 } 545 }
615 546
547 void PrinterJobHandler::OnReceivePrinterCaps(
548 bool succeeded,
549 const std::string& printer_name,
550 const printing::PrinterCapsAndDefaults& caps_and_defaults) {
551 printing::PrinterBasicInfo printer_info;
552 if (printer_watcher_)
553 printer_watcher_->GetCurrentPrinterInfo(&printer_info);
554
555 std::string post_data;
556 std::string mime_boundary;
557 cloud_print::CreateMimeBoundaryForUpload(&mime_boundary);
558
559 if (succeeded) {
560 std::string caps_hash =
561 base::MD5String(caps_and_defaults.printer_capabilities);
562 if (caps_hash != printer_info_cloud_.caps_hash) {
563 // Hashes don't match, we need to upload new capabilities (the defaults
564 // go for free along with the capabilities)
565 printer_info_cloud_.caps_hash = caps_hash;
566 cloud_print::AddMultipartValueForUpload(kPrinterCapsValue,
567 caps_and_defaults.printer_capabilities, mime_boundary,
568 caps_and_defaults.caps_mime_type, &post_data);
569 cloud_print::AddMultipartValueForUpload(kPrinterDefaultsValue,
570 caps_and_defaults.printer_defaults, mime_boundary,
571 caps_and_defaults.defaults_mime_type, &post_data);
572 cloud_print::AddMultipartValueForUpload(kPrinterCapsHashValue,
573 caps_hash, mime_boundary, std::string(), &post_data);
574 }
575 } else {
576 LOG(ERROR) << "Failed to get printer caps and defaults for printer: "
577 << printer_name;
578 }
579
580 std::string tags_hash =
581 CloudPrintHelpers::GenerateHashOfStringMap(printer_info.options);
582 if (tags_hash != printer_info_cloud_.tags_hash) {
583 printer_info_cloud_.tags_hash = tags_hash;
584 CloudPrintHelpers::GenerateMultipartPostDataForPrinterTags(
585 printer_info.options, mime_boundary, &post_data);
586 // Remove all the exising proxy tags.
587 std::string cp_tag_wildcard(kProxyTagPrefix);
588 cp_tag_wildcard += ".*";
589 cloud_print::AddMultipartValueForUpload(kPrinterRemoveTagValue,
590 cp_tag_wildcard, mime_boundary, std::string(), &post_data);
591 }
592
593 if (printer_info.printer_name != printer_info_.printer_name) {
594 cloud_print::AddMultipartValueForUpload(kPrinterNameValue,
595 printer_info.printer_name, mime_boundary, std::string(), &post_data);
596 }
597 if (printer_info.printer_description != printer_info_.printer_description) {
598 cloud_print::AddMultipartValueForUpload(kPrinterDescValue,
599 printer_info.printer_description, mime_boundary,
600 std::string(), &post_data);
601 }
602 if (printer_info.printer_status != printer_info_.printer_status) {
603 cloud_print::AddMultipartValueForUpload(kPrinterStatusValue,
604 base::StringPrintf("%d", printer_info.printer_status), mime_boundary,
605 std::string(), &post_data);
606 }
607 printer_info_ = printer_info;
608 if (!post_data.empty()) {
609 // Terminate the request body
610 post_data.append("--" + mime_boundary + "--\r\n");
611 std::string mime_type("multipart/form-data; boundary=");
612 mime_type += mime_boundary;
613 SetNextJSONHandler(&PrinterJobHandler::HandlePrinterUpdateResponse);
614 request_ = new CloudPrintURLFetcher;
615 request_->StartPostRequest(
616 CloudPrintHelpers::GetUrlForPrinterUpdate(
617 cloud_print_server_url_, printer_info_cloud_.printer_id),
618 this,
619 kCloudPrintAPIMaxRetryCount,
620 mime_type,
621 post_data,
622 std::string());
623 } else {
624 // We are done here. Go to the Stop state
625 MessageLoop::current()->PostTask(
626 FROM_HERE, base::Bind(&PrinterJobHandler::Stop, this));
627 }
628 }
629
616 // The following methods are called on |print_thread_|. It is not safe to 630 // The following methods are called on |print_thread_|. It is not safe to
617 // access any members other than |job_handler_message_loop_proxy_|, 631 // access any members other than |job_handler_message_loop_proxy_|,
618 // |job_spooler_| and |print_system_|. 632 // |job_spooler_| and |print_system_|.
619 void PrinterJobHandler::DoPrint(const JobDetails& job_details, 633 void PrinterJobHandler::DoPrint(const JobDetails& job_details,
620 const std::string& printer_name) { 634 const std::string& printer_name) {
621 job_spooler_ = print_system_->CreateJobSpooler(); 635 job_spooler_ = print_system_->CreateJobSpooler();
622 DCHECK(job_spooler_); 636 DCHECK(job_spooler_);
623 if (!job_spooler_ || !job_spooler_->Spool(job_details.print_ticket_, 637 if (!job_spooler_ || !job_spooler_->Spool(job_details.print_ticket_,
624 job_details.print_data_file_path_, 638 job_details.print_data_file_path_,
625 job_details.print_data_mime_type_, 639 job_details.print_data_mime_type_,
626 printer_name, 640 printer_name,
627 job_details.job_title_, 641 job_details.job_title_,
628 job_details.tags_, 642 job_details.tags_,
629 this)) { 643 this)) {
630 OnJobSpoolFailed(); 644 OnJobSpoolFailed();
631 } 645 }
632 } 646 }
633
634 void PrinterJobHandler::OnJobSpoolSucceeded(
635 const cloud_print::PlatformJobId& job_id) {
636 DCHECK(MessageLoop::current() == print_thread_.message_loop());
637 job_spooler_ = NULL;
638 job_handler_message_loop_proxy_->PostTask(
639 FROM_HERE, base::Bind(&PrinterJobHandler::JobSpooled, this, job_id));
640 }
641
642 void PrinterJobHandler::OnJobSpoolFailed() {
643 DCHECK(MessageLoop::current() == print_thread_.message_loop());
644 job_spooler_ = NULL;
645 job_handler_message_loop_proxy_->PostTask(
646 FROM_HERE, base::Bind(&PrinterJobHandler::JobFailed, this, PRINT_FAILED));
647 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698