| OLD | NEW |
| 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/cloud_print_connector.h" | 5 #include "chrome/service/cloud_print/cloud_print_connector.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/md5.h" | 9 #include "base/md5.h" |
| 10 #include "base/rand_util.h" | 10 #include "base/rand_util.h" |
| 11 #include "base/string_number_conversions.h" | 11 #include "base/string_number_conversions.h" |
| 12 #include "base/string_split.h" | 12 #include "base/string_split.h" |
| 13 #include "base/stringprintf.h" | 13 #include "base/stringprintf.h" |
| 14 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
| 15 #include "base/values.h" | 15 #include "base/values.h" |
| 16 #include "chrome/common/cloud_print/cloud_print_helpers.h" | 16 #include "chrome/common/cloud_print/cloud_print_helpers.h" |
| 17 #include "chrome/service/cloud_print/cloud_print_consts.h" | 17 #include "chrome/service/cloud_print/cloud_print_consts.h" |
| 18 #include "chrome/service/cloud_print/cloud_print_helpers.h" | 18 #include "chrome/service/cloud_print/cloud_print_helpers.h" |
| 19 #include "grit/generated_resources.h" | 19 #include "grit/generated_resources.h" |
| 20 #include "ui/base/l10n/l10n_util.h" | 20 #include "ui/base/l10n/l10n_util.h" |
| 21 | 21 |
| 22 const char kDeleteOnEnumFail[] = "delete_on_enum_fail"; | 22 CloudPrintConnector::CloudPrintConnector(Client* client, |
| 23 | 23 const ConnectorSettings& settings) |
| 24 CloudPrintConnector::CloudPrintConnector( | |
| 25 Client* client, | |
| 26 const std::string& proxy_id, | |
| 27 const GURL& cloud_print_server_url, | |
| 28 const DictionaryValue* print_system_settings) | |
| 29 : client_(client), | 24 : client_(client), |
| 30 proxy_id_(proxy_id), | 25 next_response_handler_(NULL) { |
| 31 cloud_print_server_url_(cloud_print_server_url), | 26 settings_.CopyFrom(settings); |
| 32 next_response_handler_(NULL), | |
| 33 delete_on_enum_fail_(false) { | |
| 34 if (print_system_settings) { | |
| 35 // It is possible to have no print settings specified. | |
| 36 print_system_settings_.reset(print_system_settings->DeepCopy()); | |
| 37 } | |
| 38 } | 27 } |
| 39 | 28 |
| 40 bool CloudPrintConnector::InitPrintSystem() { | 29 bool CloudPrintConnector::InitPrintSystem() { |
| 41 if (print_system_.get()) | 30 if (print_system_.get()) |
| 42 return true; | 31 return true; |
| 43 print_system_ = cloud_print::PrintSystem::CreateInstance( | 32 print_system_ = cloud_print::PrintSystem::CreateInstance( |
| 44 print_system_settings_.get()); | 33 settings_.print_system_settings()); |
| 45 if (!print_system_.get()) { | 34 if (!print_system_.get()) { |
| 46 NOTREACHED(); | 35 NOTREACHED(); |
| 47 return false; // No memory. | 36 return false; // No memory. |
| 48 } | 37 } |
| 49 if (print_system_settings_.get()) { | |
| 50 bool delete_on_enum_fail = false; | |
| 51 print_system_settings_->GetBoolean(kDeleteOnEnumFail, | |
| 52 &delete_on_enum_fail); | |
| 53 delete_on_enum_fail_ = delete_on_enum_fail; | |
| 54 } | |
| 55 cloud_print::PrintSystem::PrintSystemResult result = print_system_->Init(); | 38 cloud_print::PrintSystem::PrintSystemResult result = print_system_->Init(); |
| 56 if (!result.succeeded()) { | 39 if (!result.succeeded()) { |
| 57 print_system_ = NULL; | 40 print_system_ = NULL; |
| 58 // We could not initialize the print system. We need to notify the server. | 41 // We could not initialize the print system. We need to notify the server. |
| 59 ReportUserMessage(kPrintSystemFailedMessageId, result.message()); | 42 ReportUserMessage(kPrintSystemFailedMessageId, result.message()); |
| 60 return false; | 43 return false; |
| 61 } | 44 } |
| 62 return true; | 45 return true; |
| 63 } | 46 } |
| 64 | 47 |
| 65 bool CloudPrintConnector::Start() { | 48 bool CloudPrintConnector::Start() { |
| 66 VLOG(1) << "CP_CONNECTOR: Starting connector" | 49 VLOG(1) << "CP_CONNECTOR: Starting connector" |
| 67 << ", proxy id: " << proxy_id_; | 50 << ", proxy id: " << settings_.proxy_id(); |
| 68 | 51 |
| 69 pending_tasks_.clear(); | 52 pending_tasks_.clear(); |
| 70 | 53 |
| 71 if (!InitPrintSystem()) | 54 if (!InitPrintSystem()) |
| 72 return false; | 55 return false; |
| 73 | 56 |
| 74 // Start watching for updates from the print system. | 57 // Start watching for updates from the print system. |
| 75 print_server_watcher_ = print_system_->CreatePrintServerWatcher(); | 58 print_server_watcher_ = print_system_->CreatePrintServerWatcher(); |
| 76 print_server_watcher_->StartWatching(this); | 59 print_server_watcher_->StartWatching(this); |
| 77 | 60 |
| 78 // Get list of registered printers. | 61 // Get list of registered printers. |
| 79 AddPendingAvailableTask(); | 62 AddPendingAvailableTask(); |
| 80 return true; | 63 return true; |
| 81 } | 64 } |
| 82 | 65 |
| 83 void CloudPrintConnector::Stop() { | 66 void CloudPrintConnector::Stop() { |
| 84 VLOG(1) << "CP_CONNECTOR: Stopping connector" | 67 VLOG(1) << "CP_CONNECTOR: Stopping connector" |
| 85 << ", proxy id: " << proxy_id_; | 68 << ", proxy id: " << settings_.proxy_id(); |
| 86 DCHECK(IsRunning()); | 69 DCHECK(IsRunning()); |
| 87 // Do uninitialization here. | 70 // Do uninitialization here. |
| 88 pending_tasks_.clear(); | 71 pending_tasks_.clear(); |
| 89 print_server_watcher_ = NULL; | 72 print_server_watcher_ = NULL; |
| 90 request_ = NULL; | 73 request_ = NULL; |
| 91 } | 74 } |
| 92 | 75 |
| 93 bool CloudPrintConnector::IsRunning() { | 76 bool CloudPrintConnector::IsRunning() { |
| 94 return print_server_watcher_.get() != NULL; | 77 return print_server_watcher_.get() != NULL; |
| 95 } | 78 } |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 DictionaryValue* printer_data = NULL; | 207 DictionaryValue* printer_data = NULL; |
| 225 if (printer_list->GetDictionary(index, &printer_data)) { | 208 if (printer_list->GetDictionary(index, &printer_data)) { |
| 226 std::string printer_name; | 209 std::string printer_name; |
| 227 printer_data->GetString(kNameValue, &printer_name); | 210 printer_data->GetString(kNameValue, &printer_name); |
| 228 if (RemovePrinterFromList(printer_name, &local_printers)) { | 211 if (RemovePrinterFromList(printer_name, &local_printers)) { |
| 229 InitJobHandlerForPrinter(printer_data); | 212 InitJobHandlerForPrinter(printer_data); |
| 230 } else { | 213 } else { |
| 231 // Cloud printer is not found on the local system. | 214 // Cloud printer is not found on the local system. |
| 232 std::string printer_id; | 215 std::string printer_id; |
| 233 printer_data->GetString(kIdValue, &printer_id); | 216 printer_data->GetString(kIdValue, &printer_id); |
| 234 if (full_list || delete_on_enum_fail_) { | 217 if (full_list || settings_.delete_on_enum_fail()) { |
| 235 // Delete if we get the full list of printers or | 218 // Delete if we get the full list of printers or |
| 236 // |delete_on_enum_fail_| is set. | 219 // |delete_on_enum_fail_| is set. |
| 237 VLOG(1) << "CP_CONNECTOR: Deleting " << printer_name << | 220 VLOG(1) << "CP_CONNECTOR: Deleting " << printer_name << |
| 238 " id: " << printer_id << | 221 " id: " << printer_id << |
| 239 " full_list: " << full_list << | 222 " full_list: " << full_list << |
| 240 " delete_on_enum_fail: " << delete_on_enum_fail_; | 223 " delete_on_enum_fail: " << settings_.delete_on_enum_fail(); |
| 241 AddPendingDeleteTask(printer_id); | 224 AddPendingDeleteTask(printer_id); |
| 242 } else { | 225 } else { |
| 243 LOG(ERROR) << "CP_CONNECTOR: Printer: " << printer_name << | 226 LOG(ERROR) << "CP_CONNECTOR: Printer: " << printer_name << |
| 244 " id: " << printer_id << | 227 " id: " << printer_id << |
| 245 " not found in print system and full printer list was" << | 228 " not found in print system and full printer list was" << |
| 246 " not received. Printer will not be able to process" << | 229 " not received. Printer will not be able to process" << |
| 247 " jobs."; | 230 " jobs."; |
| 248 } | 231 } |
| 249 } | 232 } |
| 250 } else { | 233 } else { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 request_->StartPostRequest( | 301 request_->StartPostRequest( |
| 319 url, this, max_retries, mime_type, post_data, std::string()); | 302 url, this, max_retries, mime_type, post_data, std::string()); |
| 320 } | 303 } |
| 321 | 304 |
| 322 void CloudPrintConnector::ReportUserMessage(const std::string& message_id, | 305 void CloudPrintConnector::ReportUserMessage(const std::string& message_id, |
| 323 const std::string& failure_msg) { | 306 const std::string& failure_msg) { |
| 324 // This is a fire and forget type of function. | 307 // This is a fire and forget type of function. |
| 325 // Result of this request will be ignored. | 308 // Result of this request will be ignored. |
| 326 std::string mime_boundary; | 309 std::string mime_boundary; |
| 327 cloud_print::CreateMimeBoundaryForUpload(&mime_boundary); | 310 cloud_print::CreateMimeBoundaryForUpload(&mime_boundary); |
| 328 GURL url = CloudPrintHelpers::GetUrlForUserMessage(cloud_print_server_url_, | 311 GURL url = CloudPrintHelpers::GetUrlForUserMessage(settings_.server_url(), |
| 329 message_id); | 312 message_id); |
| 330 std::string post_data; | 313 std::string post_data; |
| 331 cloud_print::AddMultipartValueForUpload(kMessageTextValue, failure_msg, | 314 cloud_print::AddMultipartValueForUpload(kMessageTextValue, failure_msg, |
| 332 mime_boundary, std::string(), &post_data); | 315 mime_boundary, std::string(), &post_data); |
| 333 // Terminate the request body | 316 // Terminate the request body |
| 334 post_data.append("--" + mime_boundary + "--\r\n"); | 317 post_data.append("--" + mime_boundary + "--\r\n"); |
| 335 std::string mime_type("multipart/form-data; boundary="); | 318 std::string mime_type("multipart/form-data; boundary="); |
| 336 mime_type += mime_boundary; | 319 mime_type += mime_boundary; |
| 337 user_message_request_ = new CloudPrintURLFetcher; | 320 user_message_request_ = new CloudPrintURLFetcher; |
| 338 user_message_request_->StartPostRequest(url, this, 1, mime_type, post_data, | 321 user_message_request_->StartPostRequest(url, this, 1, mime_type, post_data, |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 base::SplitStringDontTrim(tag, '=', &tag_parts); | 370 base::SplitStringDontTrim(tag, '=', &tag_parts); |
| 388 DCHECK_EQ(tag_parts.size(), 2U); | 371 DCHECK_EQ(tag_parts.size(), 2U); |
| 389 if (tag_parts.size() == 2) | 372 if (tag_parts.size() == 2) |
| 390 printer_info_cloud.tags_hash = tag_parts[1]; | 373 printer_info_cloud.tags_hash = tag_parts[1]; |
| 391 } | 374 } |
| 392 } | 375 } |
| 393 } | 376 } |
| 394 scoped_refptr<PrinterJobHandler> job_handler; | 377 scoped_refptr<PrinterJobHandler> job_handler; |
| 395 job_handler = new PrinterJobHandler(printer_info, | 378 job_handler = new PrinterJobHandler(printer_info, |
| 396 printer_info_cloud, | 379 printer_info_cloud, |
| 397 cloud_print_server_url_, | 380 settings_.server_url(), |
| 398 print_system_.get(), | 381 print_system_.get(), |
| 399 this); | 382 this); |
| 400 job_handler_map_[printer_info_cloud.printer_id] = job_handler; | 383 job_handler_map_[printer_info_cloud.printer_id] = job_handler; |
| 401 job_handler->Initialize(); | 384 job_handler->Initialize(); |
| 402 } | 385 } |
| 403 | 386 |
| 404 void CloudPrintConnector::AddPendingAvailableTask() { | 387 void CloudPrintConnector::AddPendingAvailableTask() { |
| 405 PendingTask task; | 388 PendingTask task; |
| 406 task.type = PENDING_PRINTERS_AVAILABLE; | 389 task.type = PENDING_PRINTERS_AVAILABLE; |
| 407 AddPendingTask(task); | 390 AddPendingTask(task); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 | 443 |
| 461 // Delete current task and repost if we have more task available. | 444 // Delete current task and repost if we have more task available. |
| 462 pending_tasks_.pop_front(); | 445 pending_tasks_.pop_front(); |
| 463 if (pending_tasks_.size() != 0) { | 446 if (pending_tasks_.size() != 0) { |
| 464 MessageLoop::current()->PostTask( | 447 MessageLoop::current()->PostTask( |
| 465 FROM_HERE, base::Bind(&CloudPrintConnector::ProcessPendingTask, this)); | 448 FROM_HERE, base::Bind(&CloudPrintConnector::ProcessPendingTask, this)); |
| 466 } | 449 } |
| 467 } | 450 } |
| 468 | 451 |
| 469 void CloudPrintConnector::OnPrintersAvailable() { | 452 void CloudPrintConnector::OnPrintersAvailable() { |
| 470 GURL printer_list_url = | 453 GURL printer_list_url = CloudPrintHelpers::GetUrlForPrinterList( |
| 471 CloudPrintHelpers::GetUrlForPrinterList(cloud_print_server_url_, | 454 settings_.server_url(), settings_.proxy_id()); |
| 472 proxy_id_); | |
| 473 StartGetRequest(printer_list_url, | 455 StartGetRequest(printer_list_url, |
| 474 kCloudPrintRegisterMaxRetryCount, | 456 kCloudPrintRegisterMaxRetryCount, |
| 475 &CloudPrintConnector::HandlePrinterListResponse); | 457 &CloudPrintConnector::HandlePrinterListResponse); |
| 476 } | 458 } |
| 477 | 459 |
| 478 void CloudPrintConnector::OnPrinterRegister( | 460 void CloudPrintConnector::OnPrinterRegister( |
| 479 const printing::PrinterBasicInfo& info) { | 461 const printing::PrinterBasicInfo& info) { |
| 480 for (JobHandlerMap::iterator it = job_handler_map_.begin(); | 462 for (JobHandlerMap::iterator it = job_handler_map_.begin(); |
| 481 it != job_handler_map_.end(); ++it) { | 463 it != job_handler_map_.end(); ++it) { |
| 482 if (IsSamePrinter(it->second->GetPrinterName(), info.printer_name)) { | 464 if (IsSamePrinter(it->second->GetPrinterName(), info.printer_name)) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 498 // Remove corresponding printer job handler. | 480 // Remove corresponding printer job handler. |
| 499 JobHandlerMap::iterator it = job_handler_map_.find(printer_id); | 481 JobHandlerMap::iterator it = job_handler_map_.find(printer_id); |
| 500 if (it != job_handler_map_.end()) { | 482 if (it != job_handler_map_.end()) { |
| 501 it->second->Shutdown(); | 483 it->second->Shutdown(); |
| 502 job_handler_map_.erase(it); | 484 job_handler_map_.erase(it); |
| 503 } | 485 } |
| 504 | 486 |
| 505 // TODO(gene): We probably should not try indefinitely here. Just once or | 487 // TODO(gene): We probably should not try indefinitely here. Just once or |
| 506 // twice should be enough. | 488 // twice should be enough. |
| 507 // Bug: http://code.google.com/p/chromium/issues/detail?id=101850 | 489 // Bug: http://code.google.com/p/chromium/issues/detail?id=101850 |
| 508 GURL url = CloudPrintHelpers::GetUrlForPrinterDelete(cloud_print_server_url_, | 490 GURL url = CloudPrintHelpers::GetUrlForPrinterDelete( |
| 509 printer_id, | 491 settings_.server_url(), printer_id, "printer_deleted"); |
| 510 "printer_deleted"); | |
| 511 StartGetRequest(url, | 492 StartGetRequest(url, |
| 512 kCloudPrintAPIMaxRetryCount, | 493 kCloudPrintAPIMaxRetryCount, |
| 513 &CloudPrintConnector::HandlePrinterDeleteResponse); | 494 &CloudPrintConnector::HandlePrinterDeleteResponse); |
| 514 } | 495 } |
| 515 | 496 |
| 516 void CloudPrintConnector::OnReceivePrinterCaps( | 497 void CloudPrintConnector::OnReceivePrinterCaps( |
| 517 bool succeeded, | 498 bool succeeded, |
| 518 const std::string& printer_name, | 499 const std::string& printer_name, |
| 519 const printing::PrinterCapsAndDefaults& caps_and_defaults) { | 500 const printing::PrinterCapsAndDefaults& caps_and_defaults) { |
| 520 if (!IsRunning()) | 501 if (!IsRunning()) |
| (...skipping 16 matching lines...) Expand all Loading... |
| 537 return; | 518 return; |
| 538 } | 519 } |
| 539 | 520 |
| 540 const printing::PrinterBasicInfo& info = pending_tasks_.front().printer_info; | 521 const printing::PrinterBasicInfo& info = pending_tasks_.front().printer_info; |
| 541 DCHECK(IsSamePrinter(info.printer_name, printer_name)); | 522 DCHECK(IsSamePrinter(info.printer_name, printer_name)); |
| 542 | 523 |
| 543 std::string mime_boundary; | 524 std::string mime_boundary; |
| 544 cloud_print::CreateMimeBoundaryForUpload(&mime_boundary); | 525 cloud_print::CreateMimeBoundaryForUpload(&mime_boundary); |
| 545 std::string post_data; | 526 std::string post_data; |
| 546 | 527 |
| 547 cloud_print::AddMultipartValueForUpload(kProxyIdValue, proxy_id_, | 528 cloud_print::AddMultipartValueForUpload(kProxyIdValue, settings_.proxy_id(), |
| 548 mime_boundary, std::string(), &post_data); | 529 mime_boundary, std::string(), &post_data); |
| 549 cloud_print::AddMultipartValueForUpload(kPrinterNameValue, info.printer_name, | 530 cloud_print::AddMultipartValueForUpload(kPrinterNameValue, info.printer_name, |
| 550 mime_boundary, std::string(), &post_data); | 531 mime_boundary, std::string(), &post_data); |
| 551 cloud_print::AddMultipartValueForUpload(kPrinterDescValue, | 532 cloud_print::AddMultipartValueForUpload(kPrinterDescValue, |
| 552 info.printer_description, mime_boundary, std::string() , &post_data); | 533 info.printer_description, mime_boundary, std::string() , &post_data); |
| 553 cloud_print::AddMultipartValueForUpload(kPrinterStatusValue, | 534 cloud_print::AddMultipartValueForUpload(kPrinterStatusValue, |
| 554 base::StringPrintf("%d", info.printer_status), | 535 base::StringPrintf("%d", info.printer_status), |
| 555 mime_boundary, std::string(), &post_data); | 536 mime_boundary, std::string(), &post_data); |
| 556 // Add printer options as tags. | 537 // Add printer options as tags. |
| 557 CloudPrintHelpers::GenerateMultipartPostDataForPrinterTags(info.options, | 538 CloudPrintHelpers::GenerateMultipartPostDataForPrinterTags(info.options, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 569 cloud_print::AddMultipartValueForUpload(kPrinterCapsHashValue, | 550 cloud_print::AddMultipartValueForUpload(kPrinterCapsHashValue, |
| 570 base::MD5String(caps_and_defaults.printer_capabilities), | 551 base::MD5String(caps_and_defaults.printer_capabilities), |
| 571 mime_boundary, std::string(), &post_data); | 552 mime_boundary, std::string(), &post_data); |
| 572 | 553 |
| 573 // Terminate the request body | 554 // Terminate the request body |
| 574 post_data.append("--" + mime_boundary + "--\r\n"); | 555 post_data.append("--" + mime_boundary + "--\r\n"); |
| 575 std::string mime_type("multipart/form-data; boundary="); | 556 std::string mime_type("multipart/form-data; boundary="); |
| 576 mime_type += mime_boundary; | 557 mime_type += mime_boundary; |
| 577 | 558 |
| 578 GURL post_url = CloudPrintHelpers::GetUrlForPrinterRegistration( | 559 GURL post_url = CloudPrintHelpers::GetUrlForPrinterRegistration( |
| 579 cloud_print_server_url_); | 560 settings_.server_url()); |
| 580 StartPostRequest(post_url, | 561 StartPostRequest(post_url, |
| 581 kCloudPrintAPIMaxRetryCount, | 562 kCloudPrintAPIMaxRetryCount, |
| 582 mime_type, | 563 mime_type, |
| 583 post_data, | 564 post_data, |
| 584 &CloudPrintConnector::HandleRegisterPrinterResponse); | 565 &CloudPrintConnector::HandleRegisterPrinterResponse); |
| 585 } | 566 } |
| 586 | 567 |
| 587 bool CloudPrintConnector::IsSamePrinter(const std::string& name1, | 568 bool CloudPrintConnector::IsSamePrinter(const std::string& name1, |
| 588 const std::string& name2) const { | 569 const std::string& name2) const { |
| 589 return (0 == base::strcasecmp(name1.c_str(), name2.c_str())); | 570 return (0 == base::strcasecmp(name1.c_str(), name2.c_str())); |
| 590 } | 571 } |
| OLD | NEW |