| 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" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 | 21 |
| 22 namespace cloud_print { | 22 namespace cloud_print { |
| 23 | 23 |
| 24 CloudPrintConnector::CloudPrintConnector(Client* client, | 24 CloudPrintConnector::CloudPrintConnector(Client* client, |
| 25 const ConnectorSettings& settings) | 25 const ConnectorSettings& settings) |
| 26 : client_(client), | 26 : client_(client), |
| 27 next_response_handler_(NULL) { | 27 next_response_handler_(NULL) { |
| 28 settings_.CopyFrom(settings); | 28 settings_.CopyFrom(settings); |
| 29 } | 29 } |
| 30 | 30 |
| 31 CloudPrintConnector::PendingTask::PendingTask() : type(PENDING_PRINTERS_NONE) {} |
| 32 |
| 33 CloudPrintConnector::PendingTask::~PendingTask() {} |
| 34 |
| 31 bool CloudPrintConnector::InitPrintSystem() { | 35 bool CloudPrintConnector::InitPrintSystem() { |
| 32 if (print_system_.get()) | 36 if (print_system_.get()) |
| 33 return true; | 37 return true; |
| 34 print_system_ = PrintSystem::CreateInstance( | 38 print_system_ = PrintSystem::CreateInstance( |
| 35 settings_.print_system_settings()); | 39 settings_.print_system_settings()); |
| 36 if (!print_system_.get()) { | 40 if (!print_system_.get()) { |
| 37 NOTREACHED(); | 41 NOTREACHED(); |
| 38 return false; // No memory. | 42 return false; // No memory. |
| 39 } | 43 } |
| 40 PrintSystem::PrintSystemResult result = print_system_->Init(); | 44 PrintSystem::PrintSystemResult result = print_system_->Init(); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 DCHECK(printer_ids); | 87 DCHECK(printer_ids); |
| 84 printer_ids->clear(); | 88 printer_ids->clear(); |
| 85 for (JobHandlerMap::const_iterator iter = job_handler_map_.begin(); | 89 for (JobHandlerMap::const_iterator iter = job_handler_map_.begin(); |
| 86 iter != job_handler_map_.end(); ++iter) { | 90 iter != job_handler_map_.end(); ++iter) { |
| 87 printer_ids->push_back(iter->first); | 91 printer_ids->push_back(iter->first); |
| 88 } | 92 } |
| 89 } | 93 } |
| 90 | 94 |
| 91 void CloudPrintConnector::RegisterPrinters( | 95 void CloudPrintConnector::RegisterPrinters( |
| 92 const printing::PrinterList& printers) { | 96 const printing::PrinterList& printers) { |
| 93 if (!settings_.connect_new_printers() || !IsRunning()) | 97 if (!IsRunning()) |
| 94 return; | 98 return; |
| 95 printing::PrinterList::const_iterator it; | 99 printing::PrinterList::const_iterator it; |
| 96 for (it = printers.begin(); it != printers.end(); ++it) { | 100 for (it = printers.begin(); it != printers.end(); ++it) { |
| 97 if (!settings_.IsPrinterBlacklisted(it->printer_name)) | 101 if (settings_.ShouldConnect(it->printer_name)) |
| 98 AddPendingRegisterTask(*it); | 102 AddPendingRegisterTask(*it, settings_.GetDisplayName(it->printer_name)); |
| 99 } | 103 } |
| 100 } | 104 } |
| 101 | 105 |
| 102 // Check for jobs for specific printer | 106 // Check for jobs for specific printer |
| 103 void CloudPrintConnector::CheckForJobs(const std::string& reason, | 107 void CloudPrintConnector::CheckForJobs(const std::string& reason, |
| 104 const std::string& printer_id) { | 108 const std::string& printer_id) { |
| 105 if (!IsRunning()) | 109 if (!IsRunning()) |
| 106 return; | 110 return; |
| 107 if (!printer_id.empty()) { | 111 if (!printer_id.empty()) { |
| 108 JobHandlerMap::iterator index = job_handler_map_.find(printer_id); | 112 JobHandlerMap::iterator index = job_handler_map_.find(printer_id); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 ListValue* printer_list = NULL; | 209 ListValue* printer_list = NULL; |
| 206 // There may be no "printers" value in the JSON | 210 // There may be no "printers" value in the JSON |
| 207 if (json_data->GetList(kPrinterListValue, &printer_list) && printer_list) { | 211 if (json_data->GetList(kPrinterListValue, &printer_list) && printer_list) { |
| 208 for (size_t index = 0; index < printer_list->GetSize(); index++) { | 212 for (size_t index = 0; index < printer_list->GetSize(); index++) { |
| 209 DictionaryValue* printer_data = NULL; | 213 DictionaryValue* printer_data = NULL; |
| 210 if (printer_list->GetDictionary(index, &printer_data)) { | 214 if (printer_list->GetDictionary(index, &printer_data)) { |
| 211 std::string printer_name; | 215 std::string printer_name; |
| 212 printer_data->GetString(kNameValue, &printer_name); | 216 printer_data->GetString(kNameValue, &printer_name); |
| 213 std::string printer_id; | 217 std::string printer_id; |
| 214 printer_data->GetString(kIdValue, &printer_id); | 218 printer_data->GetString(kIdValue, &printer_id); |
| 215 if (settings_.IsPrinterBlacklisted(printer_name)) { | 219 |
| 220 if (!settings_.ShouldConnect(printer_name)) { |
| 216 VLOG(1) << "CP_CONNECTOR: Deleting " << printer_name << | 221 VLOG(1) << "CP_CONNECTOR: Deleting " << printer_name << |
| 217 " id: " << printer_id << " as blacklisted"; | 222 " id: " << printer_id << " as blacklisted"; |
| 218 AddPendingDeleteTask(printer_id); | 223 AddPendingDeleteTask(printer_id); |
| 219 } else if (RemovePrinterFromList(printer_name, &local_printers)) { | 224 } else if (RemovePrinterFromList(printer_name, &local_printers)) { |
| 220 InitJobHandlerForPrinter(printer_data); | 225 InitJobHandlerForPrinter(printer_data); |
| 221 } else { | 226 } else { |
| 222 // Cloud printer is not found on the local system. | 227 // Cloud printer is not found on the local system. |
| 223 if (full_list || settings_.delete_on_enum_fail()) { | 228 if (full_list || settings_.delete_on_enum_fail()) { |
| 224 // Delete if we get the full list of printers or | 229 // Delete if we get the full list of printers or |
| 225 // |delete_on_enum_fail_| is set. | 230 // |delete_on_enum_fail_| is set. |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 } | 397 } |
| 393 | 398 |
| 394 void CloudPrintConnector::AddPendingDeleteTask(const std::string& id) { | 399 void CloudPrintConnector::AddPendingDeleteTask(const std::string& id) { |
| 395 PendingTask task; | 400 PendingTask task; |
| 396 task.type = PENDING_PRINTER_DELETE; | 401 task.type = PENDING_PRINTER_DELETE; |
| 397 task.printer_id = id; | 402 task.printer_id = id; |
| 398 AddPendingTask(task); | 403 AddPendingTask(task); |
| 399 } | 404 } |
| 400 | 405 |
| 401 void CloudPrintConnector::AddPendingRegisterTask( | 406 void CloudPrintConnector::AddPendingRegisterTask( |
| 402 const printing::PrinterBasicInfo& info) { | 407 const printing::PrinterBasicInfo& info, |
| 408 const std::string& display_name) { |
| 403 PendingTask task; | 409 PendingTask task; |
| 404 task.type = PENDING_PRINTER_REGISTER; | 410 task.type = PENDING_PRINTER_REGISTER; |
| 405 task.printer_info = info; | 411 task.printer_info = info; |
| 412 task.display_name = display_name; |
| 406 AddPendingTask(task); | 413 AddPendingTask(task); |
| 407 } | 414 } |
| 408 | 415 |
| 409 void CloudPrintConnector::AddPendingTask(const PendingTask& task) { | 416 void CloudPrintConnector::AddPendingTask(const PendingTask& task) { |
| 410 pending_tasks_.push_back(task); | 417 pending_tasks_.push_back(task); |
| 411 // If this is the only pending task, we need to start the process. | 418 // If this is the only pending task, we need to start the process. |
| 412 if (pending_tasks_.size() == 1) { | 419 if (pending_tasks_.size() == 1) { |
| 413 MessageLoop::current()->PostTask( | 420 MessageLoop::current()->PostTask( |
| 414 FROM_HERE, base::Bind(&CloudPrintConnector::ProcessPendingTask, this)); | 421 FROM_HERE, base::Bind(&CloudPrintConnector::ProcessPendingTask, this)); |
| 415 } | 422 } |
| 416 } | 423 } |
| 417 | 424 |
| 418 void CloudPrintConnector::ProcessPendingTask() { | 425 void CloudPrintConnector::ProcessPendingTask() { |
| 419 if (!IsRunning()) | 426 if (!IsRunning()) |
| 420 return; // Orphant call. | 427 return; // Orphant call. |
| 421 if (pending_tasks_.size() == 0) | 428 if (pending_tasks_.size() == 0) |
| 422 return; // No peding tasks. | 429 return; // No peding tasks. |
| 423 | 430 |
| 424 PendingTask task = pending_tasks_.front(); | 431 PendingTask task = pending_tasks_.front(); |
| 425 | 432 |
| 426 switch (task.type) { | 433 switch (task.type) { |
| 427 case PENDING_PRINTERS_AVAILABLE : | 434 case PENDING_PRINTERS_AVAILABLE : |
| 428 OnPrintersAvailable(); | 435 OnPrintersAvailable(); |
| 429 break; | 436 break; |
| 430 case PENDING_PRINTER_REGISTER : | 437 case PENDING_PRINTER_REGISTER : |
| 431 OnPrinterRegister(task.printer_info); | 438 OnPrinterRegister(task.printer_info, task.display_name); |
| 432 break; | 439 break; |
| 433 case PENDING_PRINTER_DELETE : | 440 case PENDING_PRINTER_DELETE : |
| 434 OnPrinterDelete(task.printer_id); | 441 OnPrinterDelete(task.printer_id); |
| 435 break; | 442 break; |
| 436 default: | 443 default: |
| 437 NOTREACHED(); | 444 NOTREACHED(); |
| 438 } | 445 } |
| 439 } | 446 } |
| 440 | 447 |
| 441 void CloudPrintConnector::ContinuePendingTaskProcessing() { | 448 void CloudPrintConnector::ContinuePendingTaskProcessing() { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 452 | 459 |
| 453 void CloudPrintConnector::OnPrintersAvailable() { | 460 void CloudPrintConnector::OnPrintersAvailable() { |
| 454 GURL printer_list_url = GetUrlForPrinterList( | 461 GURL printer_list_url = GetUrlForPrinterList( |
| 455 settings_.server_url(), settings_.proxy_id()); | 462 settings_.server_url(), settings_.proxy_id()); |
| 456 StartGetRequest(printer_list_url, | 463 StartGetRequest(printer_list_url, |
| 457 kCloudPrintRegisterMaxRetryCount, | 464 kCloudPrintRegisterMaxRetryCount, |
| 458 &CloudPrintConnector::HandlePrinterListResponse); | 465 &CloudPrintConnector::HandlePrinterListResponse); |
| 459 } | 466 } |
| 460 | 467 |
| 461 void CloudPrintConnector::OnPrinterRegister( | 468 void CloudPrintConnector::OnPrinterRegister( |
| 462 const printing::PrinterBasicInfo& info) { | 469 const printing::PrinterBasicInfo& info, const std::string& display_name) { |
| 463 for (JobHandlerMap::iterator it = job_handler_map_.begin(); | 470 for (JobHandlerMap::iterator it = job_handler_map_.begin(); |
| 464 it != job_handler_map_.end(); ++it) { | 471 it != job_handler_map_.end(); ++it) { |
| 465 if (IsSamePrinter(it->second->GetPrinterName(), info.printer_name)) { | 472 if (IsSamePrinter(it->second->GetPrinterName(), info.printer_name)) { |
| 466 // Printer already registered, continue to the next task. | 473 // Printer already registered, continue to the next task. |
| 467 ContinuePendingTaskProcessing(); | 474 ContinuePendingTaskProcessing(); |
| 468 return; | 475 return; |
| 469 } | 476 } |
| 470 } | 477 } |
| 471 | 478 |
| 472 // Asynchronously fetch the printer caps and defaults. The story will | 479 // Asynchronously fetch the printer caps and defaults. The story will |
| 473 // continue in OnReceivePrinterCaps. | 480 // continue in OnReceivePrinterCaps. |
| 474 print_system_->GetPrinterCapsAndDefaults( | 481 print_system_->GetPrinterCapsAndDefaults( |
| 475 info.printer_name.c_str(), | 482 info.printer_name.c_str(), |
| 476 base::Bind(&CloudPrintConnector::OnReceivePrinterCaps, | 483 base::Bind(&CloudPrintConnector::OnReceivePrinterCaps, |
| 477 base::Unretained(this))); | 484 base::Unretained(this), display_name)); |
| 478 } | 485 } |
| 479 | 486 |
| 480 void CloudPrintConnector::OnPrinterDelete(const std::string& printer_id) { | 487 void CloudPrintConnector::OnPrinterDelete(const std::string& printer_id) { |
| 481 // Remove corresponding printer job handler. | 488 // Remove corresponding printer job handler. |
| 482 JobHandlerMap::iterator it = job_handler_map_.find(printer_id); | 489 JobHandlerMap::iterator it = job_handler_map_.find(printer_id); |
| 483 if (it != job_handler_map_.end()) { | 490 if (it != job_handler_map_.end()) { |
| 484 it->second->Shutdown(); | 491 it->second->Shutdown(); |
| 485 job_handler_map_.erase(it); | 492 job_handler_map_.erase(it); |
| 486 } | 493 } |
| 487 | 494 |
| 488 // TODO(gene): We probably should not try indefinitely here. Just once or | 495 // TODO(gene): We probably should not try indefinitely here. Just once or |
| 489 // twice should be enough. | 496 // twice should be enough. |
| 490 // Bug: http://code.google.com/p/chromium/issues/detail?id=101850 | 497 // Bug: http://code.google.com/p/chromium/issues/detail?id=101850 |
| 491 GURL url = GetUrlForPrinterDelete( | 498 GURL url = GetUrlForPrinterDelete( |
| 492 settings_.server_url(), printer_id, "printer_deleted"); | 499 settings_.server_url(), printer_id, "printer_deleted"); |
| 493 StartGetRequest(url, | 500 StartGetRequest(url, |
| 494 kCloudPrintAPIMaxRetryCount, | 501 kCloudPrintAPIMaxRetryCount, |
| 495 &CloudPrintConnector::HandlePrinterDeleteResponse); | 502 &CloudPrintConnector::HandlePrinterDeleteResponse); |
| 496 } | 503 } |
| 497 | 504 |
| 498 void CloudPrintConnector::OnReceivePrinterCaps( | 505 void CloudPrintConnector::OnReceivePrinterCaps( |
| 506 const std::string& display_name, |
| 499 bool succeeded, | 507 bool succeeded, |
| 500 const std::string& printer_name, | 508 const std::string& printer_name, |
| 501 const printing::PrinterCapsAndDefaults& caps_and_defaults) { | 509 const printing::PrinterCapsAndDefaults& caps_and_defaults) { |
| 502 if (!IsRunning()) | 510 if (!IsRunning()) |
| 503 return; // Orphant call. | 511 return; // Orphant call. |
| 504 DCHECK(pending_tasks_.size() > 0 && | 512 DCHECK(pending_tasks_.size() > 0 && |
| 505 pending_tasks_.front().type == PENDING_PRINTER_REGISTER); | 513 pending_tasks_.front().type == PENDING_PRINTER_REGISTER); |
| 506 | 514 |
| 507 if (!succeeded) { | 515 if (!succeeded) { |
| 508 LOG(ERROR) << "CP_CONNECTOR: Failed to get printer info" | 516 LOG(ERROR) << "CP_CONNECTOR: Failed to get printer info" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 523 DCHECK(IsSamePrinter(info.printer_name, printer_name)); | 531 DCHECK(IsSamePrinter(info.printer_name, printer_name)); |
| 524 | 532 |
| 525 std::string mime_boundary; | 533 std::string mime_boundary; |
| 526 CreateMimeBoundaryForUpload(&mime_boundary); | 534 CreateMimeBoundaryForUpload(&mime_boundary); |
| 527 std::string post_data; | 535 std::string post_data; |
| 528 | 536 |
| 529 AddMultipartValueForUpload(kProxyIdValue, | 537 AddMultipartValueForUpload(kProxyIdValue, |
| 530 settings_.proxy_id(), mime_boundary, std::string(), &post_data); | 538 settings_.proxy_id(), mime_boundary, std::string(), &post_data); |
| 531 AddMultipartValueForUpload(kPrinterNameValue, | 539 AddMultipartValueForUpload(kPrinterNameValue, |
| 532 info.printer_name, mime_boundary, std::string(), &post_data); | 540 info.printer_name, mime_boundary, std::string(), &post_data); |
| 541 if (!display_name.empty()) { |
| 542 AddMultipartValueForUpload(kPrinterDisplayNameValue, |
| 543 display_name, mime_boundary, std::string(), &post_data); |
| 544 } |
| 533 AddMultipartValueForUpload(kPrinterDescValue, | 545 AddMultipartValueForUpload(kPrinterDescValue, |
| 534 info.printer_description, mime_boundary, std::string(), &post_data); | 546 info.printer_description, mime_boundary, std::string(), &post_data); |
| 535 AddMultipartValueForUpload(kPrinterStatusValue, | 547 AddMultipartValueForUpload(kPrinterStatusValue, |
| 536 base::StringPrintf("%d", info.printer_status), | 548 base::StringPrintf("%d", info.printer_status), |
| 537 mime_boundary, std::string(), &post_data); | 549 mime_boundary, std::string(), &post_data); |
| 538 post_data += GetPostDataForPrinterInfo(info, mime_boundary); | 550 post_data += GetPostDataForPrinterInfo(info, mime_boundary); |
| 539 AddMultipartValueForUpload(kPrinterCapsValue, | 551 AddMultipartValueForUpload(kPrinterCapsValue, |
| 540 caps_and_defaults.printer_capabilities, mime_boundary, | 552 caps_and_defaults.printer_capabilities, mime_boundary, |
| 541 caps_and_defaults.caps_mime_type, &post_data); | 553 caps_and_defaults.caps_mime_type, &post_data); |
| 542 AddMultipartValueForUpload(kPrinterDefaultsValue, | 554 AddMultipartValueForUpload(kPrinterDefaultsValue, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 560 post_data, | 572 post_data, |
| 561 &CloudPrintConnector::HandleRegisterPrinterResponse); | 573 &CloudPrintConnector::HandleRegisterPrinterResponse); |
| 562 } | 574 } |
| 563 | 575 |
| 564 bool CloudPrintConnector::IsSamePrinter(const std::string& name1, | 576 bool CloudPrintConnector::IsSamePrinter(const std::string& name1, |
| 565 const std::string& name2) const { | 577 const std::string& name2) const { |
| 566 return (0 == base::strcasecmp(name1.c_str(), name2.c_str())); | 578 return (0 == base::strcasecmp(name1.c_str(), name2.c_str())); |
| 567 } | 579 } |
| 568 | 580 |
| 569 } // namespace cloud_print | 581 } // namespace cloud_print |
| OLD | NEW |