| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/browser/local_discovery/privet_http_impl.h" | 5 #include "chrome/browser/local_discovery/privet_http_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> |
| 8 | 9 |
| 9 #include "base/bind.h" | 10 #include "base/bind.h" |
| 10 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
| 11 #include "base/rand_util.h" | 12 #include "base/rand_util.h" |
| 12 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
| 13 #include "chrome/browser/local_discovery/privet_constants.h" | 14 #include "chrome/browser/local_discovery/privet_constants.h" |
| 14 #include "net/base/url_util.h" | 15 #include "net/base/url_util.h" |
| 15 #include "url/gurl.h" | 16 #include "url/gurl.h" |
| 16 | 17 |
| 17 namespace local_discovery { | 18 namespace local_discovery { |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 const PrivetURLFetcher::TokenCallback& callback) { | 362 const PrivetURLFetcher::TokenCallback& callback) { |
| 362 privet_client_->RefreshPrivetToken(callback); | 363 privet_client_->RefreshPrivetToken(callback); |
| 363 } | 364 } |
| 364 | 365 |
| 365 PrivetLocalPrintOperationImpl::PrivetLocalPrintOperationImpl( | 366 PrivetLocalPrintOperationImpl::PrivetLocalPrintOperationImpl( |
| 366 PrivetHTTPClientImpl* privet_client, | 367 PrivetHTTPClientImpl* privet_client, |
| 367 PrivetLocalPrintOperation::Delegate* delegate) | 368 PrivetLocalPrintOperation::Delegate* delegate) |
| 368 : privet_client_(privet_client), delegate_(delegate), | 369 : privet_client_(privet_client), delegate_(delegate), |
| 369 use_pdf_(false), has_capabilities_(false), has_extended_workflow_(false), | 370 use_pdf_(false), has_capabilities_(false), has_extended_workflow_(false), |
| 370 started_(false), offline_(false), invalid_job_retries_(0), | 371 started_(false), offline_(false), invalid_job_retries_(0), |
| 372 pwg_raster_converter_(PWGRasterConverter::CreateDefault()), |
| 371 weak_factory_(this) { | 373 weak_factory_(this) { |
| 372 } | 374 } |
| 373 | 375 |
| 374 PrivetLocalPrintOperationImpl::~PrivetLocalPrintOperationImpl() { | 376 PrivetLocalPrintOperationImpl::~PrivetLocalPrintOperationImpl() { |
| 375 } | 377 } |
| 376 | 378 |
| 377 void PrivetLocalPrintOperationImpl::Start() { | 379 void PrivetLocalPrintOperationImpl::Start() { |
| 378 DCHECK(!started_); | 380 DCHECK(!started_); |
| 379 | 381 |
| 380 // We need to get the /info response so we can know which APIs are available. | 382 // We need to get the /info response so we can know which APIs are available. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 } | 422 } |
| 421 } | 423 } |
| 422 | 424 |
| 423 void PrivetLocalPrintOperationImpl::StartInitialRequest() { | 425 void PrivetLocalPrintOperationImpl::StartInitialRequest() { |
| 424 if (has_capabilities_) { | 426 if (has_capabilities_) { |
| 425 GetCapabilities(); | 427 GetCapabilities(); |
| 426 } else { | 428 } else { |
| 427 // Since we have no capabiltties, the only reasonable format we can | 429 // Since we have no capabiltties, the only reasonable format we can |
| 428 // request is PWG Raster. | 430 // request is PWG Raster. |
| 429 use_pdf_ = false; | 431 use_pdf_ = false; |
| 430 delegate_->OnPrivetPrintingRequestPWGRaster(this); | 432 StartConvertToPWG(); |
| 431 } | 433 } |
| 432 } | 434 } |
| 433 | 435 |
| 434 void PrivetLocalPrintOperationImpl::GetCapabilities() { | 436 void PrivetLocalPrintOperationImpl::GetCapabilities() { |
| 435 current_response_ = base::Bind( | 437 current_response_ = base::Bind( |
| 436 &PrivetLocalPrintOperationImpl::OnCapabilitiesResponse, | 438 &PrivetLocalPrintOperationImpl::OnCapabilitiesResponse, |
| 437 base::Unretained(this)); | 439 base::Unretained(this)); |
| 438 | 440 |
| 439 url_fetcher_= privet_client_->CreateURLFetcher( | 441 url_fetcher_= privet_client_->CreateURLFetcher( |
| 440 CreatePrivetURL(kPrivetCapabilitiesPath), net::URLFetcher::GET, this); | 442 CreatePrivetURL(kPrivetCapabilitiesPath), net::URLFetcher::GET, this); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 | 484 |
| 483 if (offline_) { | 485 if (offline_) { |
| 484 url = net::AppendQueryParameter(url, | 486 url = net::AppendQueryParameter(url, |
| 485 kPrivetURLKeyOffline, | 487 kPrivetURLKeyOffline, |
| 486 kPrivetURLValueOffline); | 488 kPrivetURLValueOffline); |
| 487 } | 489 } |
| 488 | 490 |
| 489 url_fetcher_= privet_client_->CreateURLFetcher( | 491 url_fetcher_= privet_client_->CreateURLFetcher( |
| 490 url, net::URLFetcher::POST, this); | 492 url, net::URLFetcher::POST, this); |
| 491 | 493 |
| 492 std::string content_type = | 494 if (!use_pdf_) { |
| 493 use_pdf_ ? kPrivetContentTypePDF : kPrivetContentTypePWGRaster; | 495 url_fetcher_->SetUploadFilePath(kPrivetContentTypePWGRaster, |
| 494 | 496 pwg_file_path_); |
| 495 DCHECK(!data_.empty() || !data_file_.empty()); | |
| 496 | |
| 497 if (!data_file_.empty()) { | |
| 498 url_fetcher_->SetUploadFilePath(content_type, data_file_); | |
| 499 } else { | 497 } else { |
| 500 url_fetcher_->SetUploadData(content_type, data_); | 498 // TODO(noamsml): Move to file-based upload data? |
| 499 std::string data_str((const char*)data_->front(), data_->size()); |
| 500 url_fetcher_->SetUploadData(kPrivetContentTypePDF, data_str); |
| 501 } | 501 } |
| 502 | 502 |
| 503 url_fetcher_->Start(); | 503 url_fetcher_->Start(); |
| 504 } | 504 } |
| 505 | 505 |
| 506 void PrivetLocalPrintOperationImpl::StartPrinting() { |
| 507 if (has_extended_workflow_ && !ticket_.empty() && jobid_.empty()) { |
| 508 DoCreatejob(); |
| 509 } else { |
| 510 DoSubmitdoc(); |
| 511 } |
| 512 } |
| 513 |
| 514 void PrivetLocalPrintOperationImpl::StartConvertToPWG() { |
| 515 pwg_raster_converter_->SetResultCallback( |
| 516 base::Bind(&PrivetLocalPrintOperationImpl::OnPWGRasterConverted, |
| 517 base::Unretained(this))); |
| 518 pwg_raster_converter_->SetPDFData(data_); |
| 519 pwg_raster_converter_->Start(); |
| 520 } |
| 521 |
| 506 void PrivetLocalPrintOperationImpl::OnCapabilitiesResponse( | 522 void PrivetLocalPrintOperationImpl::OnCapabilitiesResponse( |
| 507 bool has_error, | 523 bool has_error, |
| 508 const base::DictionaryValue* value) { | 524 const base::DictionaryValue* value) { |
| 509 if (has_error) { | 525 if (has_error) { |
| 510 delegate_->OnPrivetPrintingError(this, 200); | 526 delegate_->OnPrivetPrintingError(this, 200); |
| 511 return; | 527 return; |
| 512 } | 528 } |
| 513 | 529 |
| 514 const base::ListValue* supported_content_types; | 530 const base::ListValue* supported_content_types; |
| 515 use_pdf_ = false; | 531 use_pdf_ = false; |
| 516 | 532 |
| 517 if (value->GetList(kPrivetCDDKeySupportedContentTypes, | 533 if (value->GetList(kPrivetCDDKeySupportedContentTypes, |
| 518 &supported_content_types)) { | 534 &supported_content_types)) { |
| 519 for (size_t i = 0; i < supported_content_types->GetSize(); | 535 for (size_t i = 0; i < supported_content_types->GetSize(); |
| 520 i++) { | 536 i++) { |
| 521 const base::DictionaryValue* content_type_value; | 537 const base::DictionaryValue* content_type_value; |
| 522 std::string content_type; | 538 std::string content_type; |
| 523 | 539 |
| 524 if (supported_content_types->GetDictionary(i, &content_type_value) && | 540 if (supported_content_types->GetDictionary(i, &content_type_value) && |
| 525 content_type_value->GetString(kPrivetCDDKeyContentType, | 541 content_type_value->GetString(kPrivetCDDKeyContentType, |
| 526 &content_type) && | 542 &content_type) && |
| 527 (content_type == kPrivetContentTypePDF || | 543 (content_type == kPrivetContentTypePDF || |
| 528 content_type == kPrivetContentTypeAny) ) { | 544 content_type == kPrivetContentTypeAny) ) { |
| 529 use_pdf_ = true; | 545 use_pdf_ = true; |
| 530 } | 546 } |
| 531 } | 547 } |
| 532 } | 548 } |
| 533 | 549 |
| 534 if (use_pdf_) | 550 if (use_pdf_) { |
| 535 delegate_->OnPrivetPrintingRequestPDF(this); | 551 StartPrinting(); |
| 536 else | 552 } else { |
| 537 delegate_->OnPrivetPrintingRequestPWGRaster(this); | 553 StartConvertToPWG(); |
| 554 } |
| 538 } | 555 } |
| 539 | 556 |
| 540 void PrivetLocalPrintOperationImpl::OnSubmitdocResponse( | 557 void PrivetLocalPrintOperationImpl::OnSubmitdocResponse( |
| 541 bool has_error, | 558 bool has_error, |
| 542 const base::DictionaryValue* value) { | 559 const base::DictionaryValue* value) { |
| 543 std::string error; | 560 std::string error; |
| 544 // This error is only relevant in the case of extended workflow: | 561 // This error is only relevant in the case of extended workflow: |
| 545 // If the print job ID is invalid, retry createjob and submitdoc, | 562 // If the print job ID is invalid, retry createjob and submitdoc, |
| 546 // rather than simply retrying the current request. | 563 // rather than simply retrying the current request. |
| 547 if (has_error && value->GetString(kPrivetKeyError, &error)) { | 564 if (has_error && value->GetString(kPrivetKeyError, &error)) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 559 timeout = static_cast<int>(timeout * random_scaling_factor); | 576 timeout = static_cast<int>(timeout * random_scaling_factor); |
| 560 | 577 |
| 561 timeout = std::max(timeout, kPrivetMinimumTimeout); | 578 timeout = std::max(timeout, kPrivetMinimumTimeout); |
| 562 | 579 |
| 563 base::MessageLoop::current()->PostDelayedTask( | 580 base::MessageLoop::current()->PostDelayedTask( |
| 564 FROM_HERE, base::Bind(&PrivetLocalPrintOperationImpl::DoCreatejob, | 581 FROM_HERE, base::Bind(&PrivetLocalPrintOperationImpl::DoCreatejob, |
| 565 weak_factory_.GetWeakPtr()), | 582 weak_factory_.GetWeakPtr()), |
| 566 base::TimeDelta::FromSeconds(timeout)); | 583 base::TimeDelta::FromSeconds(timeout)); |
| 567 } else if (use_pdf_ && error == kPrivetErrorInvalidDocumentType) { | 584 } else if (use_pdf_ && error == kPrivetErrorInvalidDocumentType) { |
| 568 use_pdf_ = false; | 585 use_pdf_ = false; |
| 569 delegate_->OnPrivetPrintingRequestPWGRaster(this); | 586 StartConvertToPWG(); |
| 570 } else { | 587 } else { |
| 571 delegate_->OnPrivetPrintingError(this, 200); | 588 delegate_->OnPrivetPrintingError(this, 200); |
| 572 } | 589 } |
| 573 | 590 |
| 574 return; | 591 return; |
| 575 } | 592 } |
| 576 | 593 |
| 577 // If we've gotten this far, there are no errors, so we've effectively | 594 // If we've gotten this far, there are no errors, so we've effectively |
| 578 // succeeded. | 595 // succeeded. |
| 579 delegate_->OnPrivetPrintingDone(this); | 596 delegate_->OnPrivetPrintingDone(this); |
| 580 } | 597 } |
| 581 | 598 |
| 582 void PrivetLocalPrintOperationImpl::OnCreatejobResponse( | 599 void PrivetLocalPrintOperationImpl::OnCreatejobResponse( |
| 583 bool has_error, | 600 bool has_error, |
| 584 const base::DictionaryValue* value) { | 601 const base::DictionaryValue* value) { |
| 585 if (has_error) { | 602 if (has_error) { |
| 586 delegate_->OnPrivetPrintingError(this, 200); | 603 delegate_->OnPrivetPrintingError(this, 200); |
| 587 return; | 604 return; |
| 588 } | 605 } |
| 589 | 606 |
| 590 // Try to get job ID from value. If not, jobid_ will be empty and we will use | 607 // Try to get job ID from value. If not, jobid_ will be empty and we will use |
| 591 // simple printing. | 608 // simple printing. |
| 592 value->GetString(kPrivetKeyJobID, &jobid_); | 609 value->GetString(kPrivetKeyJobID, &jobid_); |
| 593 | 610 |
| 594 DoSubmitdoc(); | 611 DoSubmitdoc(); |
| 595 } | 612 } |
| 596 | 613 |
| 614 void PrivetLocalPrintOperationImpl::OnPWGRasterConverted( |
| 615 bool success, |
| 616 const base::FilePath& pwg_file_path) { |
| 617 if (!success) { |
| 618 delegate_->OnPrivetPrintingError(this, -1); |
| 619 return; |
| 620 } |
| 621 |
| 622 DCHECK(!pwg_file_path.empty()); |
| 623 |
| 624 pwg_file_path_ = pwg_file_path; |
| 625 StartPrinting(); |
| 626 } |
| 627 |
| 597 PrivetHTTPClient* PrivetLocalPrintOperationImpl::GetHTTPClient() { | 628 PrivetHTTPClient* PrivetLocalPrintOperationImpl::GetHTTPClient() { |
| 598 return privet_client_; | 629 return privet_client_; |
| 599 } | 630 } |
| 600 | 631 |
| 601 void PrivetLocalPrintOperationImpl::OnError( | 632 void PrivetLocalPrintOperationImpl::OnError( |
| 602 PrivetURLFetcher* fetcher, | 633 PrivetURLFetcher* fetcher, |
| 603 PrivetURLFetcher::ErrorType error) { | 634 PrivetURLFetcher::ErrorType error) { |
| 604 delegate_->OnPrivetPrintingError(this, -1); | 635 delegate_->OnPrivetPrintingError(this, -1); |
| 605 } | 636 } |
| 606 | 637 |
| 607 void PrivetLocalPrintOperationImpl::OnParsedJson( | 638 void PrivetLocalPrintOperationImpl::OnParsedJson( |
| 608 PrivetURLFetcher* fetcher, | 639 PrivetURLFetcher* fetcher, |
| 609 const base::DictionaryValue* value, | 640 const base::DictionaryValue* value, |
| 610 bool has_error) { | 641 bool has_error) { |
| 611 DCHECK(!current_response_.is_null()); | 642 DCHECK(!current_response_.is_null()); |
| 612 current_response_.Run(has_error, value); | 643 current_response_.Run(has_error, value); |
| 613 } | 644 } |
| 614 | 645 |
| 615 void PrivetLocalPrintOperationImpl::OnNeedPrivetToken( | 646 void PrivetLocalPrintOperationImpl::OnNeedPrivetToken( |
| 616 PrivetURLFetcher* fetcher, | 647 PrivetURLFetcher* fetcher, |
| 617 const PrivetURLFetcher::TokenCallback& callback) { | 648 const PrivetURLFetcher::TokenCallback& callback) { |
| 618 privet_client_->RefreshPrivetToken(callback); | 649 privet_client_->RefreshPrivetToken(callback); |
| 619 } | 650 } |
| 620 | 651 |
| 621 void PrivetLocalPrintOperationImpl::SendData(const std::string& data) { | 652 void PrivetLocalPrintOperationImpl::SetData( |
| 622 DCHECK(started_); | 653 scoped_refptr<base::RefCountedBytes> data) { |
| 623 DCHECK(data_file_.empty()); | 654 DCHECK(!started_); |
| 624 data_ = data; | 655 data_ = data; |
| 625 | |
| 626 SendDataInternal(); | |
| 627 } | |
| 628 | |
| 629 void PrivetLocalPrintOperationImpl::SendDataFile( | |
| 630 const base::FilePath& data_file) { | |
| 631 DCHECK(started_); | |
| 632 DCHECK(data_.empty()); | |
| 633 data_file_ = data_file; | |
| 634 | |
| 635 SendDataInternal(); | |
| 636 } | 656 } |
| 637 | 657 |
| 638 void PrivetLocalPrintOperationImpl::SetTicket(const std::string& ticket) { | 658 void PrivetLocalPrintOperationImpl::SetTicket(const std::string& ticket) { |
| 639 DCHECK(!started_); | 659 DCHECK(!started_); |
| 640 ticket_ = ticket; | 660 ticket_ = ticket; |
| 641 } | 661 } |
| 642 | 662 |
| 643 void PrivetLocalPrintOperationImpl::SetUsername(const std::string& user) { | 663 void PrivetLocalPrintOperationImpl::SetUsername(const std::string& user) { |
| 644 DCHECK(!started_); | 664 DCHECK(!started_); |
| 645 user_= user; | 665 user_= user; |
| 646 } | 666 } |
| 647 | 667 |
| 648 void PrivetLocalPrintOperationImpl::SetJobname(const std::string& jobname) { | 668 void PrivetLocalPrintOperationImpl::SetJobname(const std::string& jobname) { |
| 649 DCHECK(!started_); | 669 DCHECK(!started_); |
| 650 jobname_ = jobname; | 670 jobname_ = jobname; |
| 651 } | 671 } |
| 652 | 672 |
| 653 void PrivetLocalPrintOperationImpl::SetOffline(bool offline) { | 673 void PrivetLocalPrintOperationImpl::SetOffline(bool offline) { |
| 654 DCHECK(!started_); | 674 DCHECK(!started_); |
| 655 offline_ = offline; | 675 offline_ = offline; |
| 656 } | 676 } |
| 657 | 677 |
| 658 void PrivetLocalPrintOperationImpl::SendDataInternal() { | 678 void PrivetLocalPrintOperationImpl::SetPWGRasterConverterForTesting( |
| 659 if (has_extended_workflow_ && !ticket_.empty() && jobid_.empty()) { | 679 scoped_ptr<PWGRasterConverter> pwg_raster_converter) { |
| 660 DoCreatejob(); | 680 pwg_raster_converter_ = pwg_raster_converter.Pass(); |
| 661 } else { | |
| 662 DoSubmitdoc(); | |
| 663 } | |
| 664 } | 681 } |
| 665 | 682 |
| 666 PrivetHTTPClientImpl::PrivetHTTPClientImpl( | 683 PrivetHTTPClientImpl::PrivetHTTPClientImpl( |
| 667 const std::string& name, | 684 const std::string& name, |
| 668 const net::HostPortPair& host_port, | 685 const net::HostPortPair& host_port, |
| 669 net::URLRequestContextGetter* request_context) | 686 net::URLRequestContextGetter* request_context) |
| 670 : name_(name), | 687 : name_(name), |
| 671 fetcher_factory_(request_context), | 688 fetcher_factory_(request_context), |
| 672 host_port_(host_port) { | 689 host_port_(host_port) { |
| 673 } | 690 } |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 761 TokenCallbackVector token_callbacks; | 778 TokenCallbackVector token_callbacks; |
| 762 token_callbacks_.swap(token_callbacks); | 779 token_callbacks_.swap(token_callbacks); |
| 763 | 780 |
| 764 for (TokenCallbackVector::iterator i = token_callbacks.begin(); | 781 for (TokenCallbackVector::iterator i = token_callbacks.begin(); |
| 765 i != token_callbacks.end(); i++) { | 782 i != token_callbacks.end(); i++) { |
| 766 i->Run(token); | 783 i->Run(token); |
| 767 } | 784 } |
| 768 } | 785 } |
| 769 | 786 |
| 770 } // namespace local_discovery | 787 } // namespace local_discovery |
| OLD | NEW |