| 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_->Start( |
| 516 data_, |
| 517 base::Bind(&PrivetLocalPrintOperationImpl::OnPWGRasterConverted, |
| 518 base::Unretained(this))); |
| 519 } |
| 520 |
| 506 void PrivetLocalPrintOperationImpl::OnCapabilitiesResponse( | 521 void PrivetLocalPrintOperationImpl::OnCapabilitiesResponse( |
| 507 bool has_error, | 522 bool has_error, |
| 508 const base::DictionaryValue* value) { | 523 const base::DictionaryValue* value) { |
| 509 if (has_error) { | 524 if (has_error) { |
| 510 delegate_->OnPrivetPrintingError(this, 200); | 525 delegate_->OnPrivetPrintingError(this, 200); |
| 511 return; | 526 return; |
| 512 } | 527 } |
| 513 | 528 |
| 514 const base::ListValue* supported_content_types; | 529 const base::ListValue* supported_content_types; |
| 515 use_pdf_ = false; | 530 use_pdf_ = false; |
| 516 | 531 |
| 517 if (value->GetList(kPrivetCDDKeySupportedContentTypes, | 532 if (value->GetList(kPrivetCDDKeySupportedContentTypes, |
| 518 &supported_content_types)) { | 533 &supported_content_types)) { |
| 519 for (size_t i = 0; i < supported_content_types->GetSize(); | 534 for (size_t i = 0; i < supported_content_types->GetSize(); |
| 520 i++) { | 535 i++) { |
| 521 const base::DictionaryValue* content_type_value; | 536 const base::DictionaryValue* content_type_value; |
| 522 std::string content_type; | 537 std::string content_type; |
| 523 | 538 |
| 524 if (supported_content_types->GetDictionary(i, &content_type_value) && | 539 if (supported_content_types->GetDictionary(i, &content_type_value) && |
| 525 content_type_value->GetString(kPrivetCDDKeyContentType, | 540 content_type_value->GetString(kPrivetCDDKeyContentType, |
| 526 &content_type) && | 541 &content_type) && |
| 527 (content_type == kPrivetContentTypePDF || | 542 (content_type == kPrivetContentTypePDF || |
| 528 content_type == kPrivetContentTypeAny) ) { | 543 content_type == kPrivetContentTypeAny) ) { |
| 529 use_pdf_ = true; | 544 use_pdf_ = true; |
| 530 } | 545 } |
| 531 } | 546 } |
| 532 } | 547 } |
| 533 | 548 |
| 534 if (use_pdf_) | 549 if (use_pdf_) { |
| 535 delegate_->OnPrivetPrintingRequestPDF(this); | 550 StartPrinting(); |
| 536 else | 551 } else { |
| 537 delegate_->OnPrivetPrintingRequestPWGRaster(this); | 552 StartConvertToPWG(); |
| 553 } |
| 538 } | 554 } |
| 539 | 555 |
| 540 void PrivetLocalPrintOperationImpl::OnSubmitdocResponse( | 556 void PrivetLocalPrintOperationImpl::OnSubmitdocResponse( |
| 541 bool has_error, | 557 bool has_error, |
| 542 const base::DictionaryValue* value) { | 558 const base::DictionaryValue* value) { |
| 543 std::string error; | 559 std::string error; |
| 544 // This error is only relevant in the case of extended workflow: | 560 // This error is only relevant in the case of extended workflow: |
| 545 // If the print job ID is invalid, retry createjob and submitdoc, | 561 // If the print job ID is invalid, retry createjob and submitdoc, |
| 546 // rather than simply retrying the current request. | 562 // rather than simply retrying the current request. |
| 547 if (has_error && value->GetString(kPrivetKeyError, &error)) { | 563 if (has_error && value->GetString(kPrivetKeyError, &error)) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 559 timeout = static_cast<int>(timeout * random_scaling_factor); | 575 timeout = static_cast<int>(timeout * random_scaling_factor); |
| 560 | 576 |
| 561 timeout = std::max(timeout, kPrivetMinimumTimeout); | 577 timeout = std::max(timeout, kPrivetMinimumTimeout); |
| 562 | 578 |
| 563 base::MessageLoop::current()->PostDelayedTask( | 579 base::MessageLoop::current()->PostDelayedTask( |
| 564 FROM_HERE, base::Bind(&PrivetLocalPrintOperationImpl::DoCreatejob, | 580 FROM_HERE, base::Bind(&PrivetLocalPrintOperationImpl::DoCreatejob, |
| 565 weak_factory_.GetWeakPtr()), | 581 weak_factory_.GetWeakPtr()), |
| 566 base::TimeDelta::FromSeconds(timeout)); | 582 base::TimeDelta::FromSeconds(timeout)); |
| 567 } else if (use_pdf_ && error == kPrivetErrorInvalidDocumentType) { | 583 } else if (use_pdf_ && error == kPrivetErrorInvalidDocumentType) { |
| 568 use_pdf_ = false; | 584 use_pdf_ = false; |
| 569 delegate_->OnPrivetPrintingRequestPWGRaster(this); | 585 StartConvertToPWG(); |
| 570 } else { | 586 } else { |
| 571 delegate_->OnPrivetPrintingError(this, 200); | 587 delegate_->OnPrivetPrintingError(this, 200); |
| 572 } | 588 } |
| 573 | 589 |
| 574 return; | 590 return; |
| 575 } | 591 } |
| 576 | 592 |
| 577 // If we've gotten this far, there are no errors, so we've effectively | 593 // If we've gotten this far, there are no errors, so we've effectively |
| 578 // succeeded. | 594 // succeeded. |
| 579 delegate_->OnPrivetPrintingDone(this); | 595 delegate_->OnPrivetPrintingDone(this); |
| 580 } | 596 } |
| 581 | 597 |
| 582 void PrivetLocalPrintOperationImpl::OnCreatejobResponse( | 598 void PrivetLocalPrintOperationImpl::OnCreatejobResponse( |
| 583 bool has_error, | 599 bool has_error, |
| 584 const base::DictionaryValue* value) { | 600 const base::DictionaryValue* value) { |
| 585 if (has_error) { | 601 if (has_error) { |
| 586 delegate_->OnPrivetPrintingError(this, 200); | 602 delegate_->OnPrivetPrintingError(this, 200); |
| 587 return; | 603 return; |
| 588 } | 604 } |
| 589 | 605 |
| 590 // Try to get job ID from value. If not, jobid_ will be empty and we will use | 606 // Try to get job ID from value. If not, jobid_ will be empty and we will use |
| 591 // simple printing. | 607 // simple printing. |
| 592 value->GetString(kPrivetKeyJobID, &jobid_); | 608 value->GetString(kPrivetKeyJobID, &jobid_); |
| 593 | 609 |
| 594 DoSubmitdoc(); | 610 DoSubmitdoc(); |
| 595 } | 611 } |
| 596 | 612 |
| 613 void PrivetLocalPrintOperationImpl::OnPWGRasterConverted( |
| 614 bool success, |
| 615 const base::FilePath& pwg_file_path) { |
| 616 if (!success) { |
| 617 delegate_->OnPrivetPrintingError(this, -1); |
| 618 return; |
| 619 } |
| 620 |
| 621 DCHECK(!pwg_file_path.empty()); |
| 622 |
| 623 pwg_file_path_ = pwg_file_path; |
| 624 StartPrinting(); |
| 625 } |
| 626 |
| 597 PrivetHTTPClient* PrivetLocalPrintOperationImpl::GetHTTPClient() { | 627 PrivetHTTPClient* PrivetLocalPrintOperationImpl::GetHTTPClient() { |
| 598 return privet_client_; | 628 return privet_client_; |
| 599 } | 629 } |
| 600 | 630 |
| 601 void PrivetLocalPrintOperationImpl::OnError( | 631 void PrivetLocalPrintOperationImpl::OnError( |
| 602 PrivetURLFetcher* fetcher, | 632 PrivetURLFetcher* fetcher, |
| 603 PrivetURLFetcher::ErrorType error) { | 633 PrivetURLFetcher::ErrorType error) { |
| 604 delegate_->OnPrivetPrintingError(this, -1); | 634 delegate_->OnPrivetPrintingError(this, -1); |
| 605 } | 635 } |
| 606 | 636 |
| 607 void PrivetLocalPrintOperationImpl::OnParsedJson( | 637 void PrivetLocalPrintOperationImpl::OnParsedJson( |
| 608 PrivetURLFetcher* fetcher, | 638 PrivetURLFetcher* fetcher, |
| 609 const base::DictionaryValue* value, | 639 const base::DictionaryValue* value, |
| 610 bool has_error) { | 640 bool has_error) { |
| 611 DCHECK(!current_response_.is_null()); | 641 DCHECK(!current_response_.is_null()); |
| 612 current_response_.Run(has_error, value); | 642 current_response_.Run(has_error, value); |
| 613 } | 643 } |
| 614 | 644 |
| 615 void PrivetLocalPrintOperationImpl::OnNeedPrivetToken( | 645 void PrivetLocalPrintOperationImpl::OnNeedPrivetToken( |
| 616 PrivetURLFetcher* fetcher, | 646 PrivetURLFetcher* fetcher, |
| 617 const PrivetURLFetcher::TokenCallback& callback) { | 647 const PrivetURLFetcher::TokenCallback& callback) { |
| 618 privet_client_->RefreshPrivetToken(callback); | 648 privet_client_->RefreshPrivetToken(callback); |
| 619 } | 649 } |
| 620 | 650 |
| 621 void PrivetLocalPrintOperationImpl::SendData(const std::string& data) { | 651 void PrivetLocalPrintOperationImpl::SetData(base::RefCountedBytes* data) { |
| 622 DCHECK(started_); | 652 DCHECK(!started_); |
| 623 DCHECK(data_file_.empty()); | |
| 624 data_ = data; | 653 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 } | 654 } |
| 637 | 655 |
| 638 void PrivetLocalPrintOperationImpl::SetTicket(const std::string& ticket) { | 656 void PrivetLocalPrintOperationImpl::SetTicket(const std::string& ticket) { |
| 639 DCHECK(!started_); | 657 DCHECK(!started_); |
| 640 ticket_ = ticket; | 658 ticket_ = ticket; |
| 641 } | 659 } |
| 642 | 660 |
| 643 void PrivetLocalPrintOperationImpl::SetUsername(const std::string& user) { | 661 void PrivetLocalPrintOperationImpl::SetUsername(const std::string& user) { |
| 644 DCHECK(!started_); | 662 DCHECK(!started_); |
| 645 user_= user; | 663 user_= user; |
| 646 } | 664 } |
| 647 | 665 |
| 648 void PrivetLocalPrintOperationImpl::SetJobname(const std::string& jobname) { | 666 void PrivetLocalPrintOperationImpl::SetJobname(const std::string& jobname) { |
| 649 DCHECK(!started_); | 667 DCHECK(!started_); |
| 650 jobname_ = jobname; | 668 jobname_ = jobname; |
| 651 } | 669 } |
| 652 | 670 |
| 653 void PrivetLocalPrintOperationImpl::SetOffline(bool offline) { | 671 void PrivetLocalPrintOperationImpl::SetOffline(bool offline) { |
| 654 DCHECK(!started_); | 672 DCHECK(!started_); |
| 655 offline_ = offline; | 673 offline_ = offline; |
| 656 } | 674 } |
| 657 | 675 |
| 658 void PrivetLocalPrintOperationImpl::SendDataInternal() { | 676 void PrivetLocalPrintOperationImpl::SetPWGRasterConverterForTesting( |
| 659 if (has_extended_workflow_ && !ticket_.empty() && jobid_.empty()) { | 677 scoped_ptr<PWGRasterConverter> pwg_raster_converter) { |
| 660 DoCreatejob(); | 678 pwg_raster_converter_ = pwg_raster_converter.Pass(); |
| 661 } else { | |
| 662 DoSubmitdoc(); | |
| 663 } | |
| 664 } | 679 } |
| 665 | 680 |
| 666 PrivetHTTPClientImpl::PrivetHTTPClientImpl( | 681 PrivetHTTPClientImpl::PrivetHTTPClientImpl( |
| 667 const std::string& name, | 682 const std::string& name, |
| 668 const net::HostPortPair& host_port, | 683 const net::HostPortPair& host_port, |
| 669 net::URLRequestContextGetter* request_context) | 684 net::URLRequestContextGetter* request_context) |
| 670 : name_(name), | 685 : name_(name), |
| 671 fetcher_factory_(request_context), | 686 fetcher_factory_(request_context), |
| 672 host_port_(host_port) { | 687 host_port_(host_port) { |
| 673 } | 688 } |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 761 TokenCallbackVector token_callbacks; | 776 TokenCallbackVector token_callbacks; |
| 762 token_callbacks_.swap(token_callbacks); | 777 token_callbacks_.swap(token_callbacks); |
| 763 | 778 |
| 764 for (TokenCallbackVector::iterator i = token_callbacks.begin(); | 779 for (TokenCallbackVector::iterator i = token_callbacks.begin(); |
| 765 i != token_callbacks.end(); i++) { | 780 i != token_callbacks.end(); i++) { |
| 766 i->Run(token); | 781 i->Run(token); |
| 767 } | 782 } |
| 768 } | 783 } |
| 769 | 784 |
| 770 } // namespace local_discovery | 785 } // namespace local_discovery |
| OLD | NEW |