| 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 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
| 12 #include "base/rand_util.h" | 12 #include "base/rand_util.h" |
| 13 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
| 14 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
| 15 #include "chrome/browser/local_discovery/privet_constants.h" | 15 #include "chrome/browser/local_discovery/privet_constants.h" |
| 16 #include "components/cloud_devices/printer_description.h" |
| 16 #include "net/base/url_util.h" | 17 #include "net/base/url_util.h" |
| 18 #include "printing/units.h" |
| 17 #include "url/gurl.h" | 19 #include "url/gurl.h" |
| 18 | 20 |
| 19 namespace local_discovery { | 21 namespace local_discovery { |
| 20 | 22 |
| 21 namespace { | 23 namespace { |
| 22 const char kUrlPlaceHolder[] = "http://host/"; | 24 const char kUrlPlaceHolder[] = "http://host/"; |
| 23 const char kPrivetRegisterActionArgName[] = "action"; | 25 const char kPrivetRegisterActionArgName[] = "action"; |
| 24 const char kPrivetRegisterUserArgName[] = "user"; | 26 const char kPrivetRegisterUserArgName[] = "user"; |
| 25 | 27 |
| 26 const char kPrivetURLKeyUserName[] = "user_name"; | 28 const char kPrivetURLKeyUserName[] = "user_name"; |
| 27 const char kPrivetURLKeyClientName[] = "client_name"; | 29 const char kPrivetURLKeyClientName[] = "client_name"; |
| 28 const char kPrivetURLKeyJobname[] = "job_name"; | 30 const char kPrivetURLKeyJobname[] = "job_name"; |
| 29 const char kPrivetURLKeyOffline[] = "offline"; | 31 const char kPrivetURLKeyOffline[] = "offline"; |
| 30 const char kPrivetURLValueOffline[] = "1"; | 32 const char kPrivetURLValueOffline[] = "1"; |
| 31 const char kPrivetURLValueClientName[] = "Chrome"; | 33 const char kPrivetURLValueClientName[] = "Chrome"; |
| 32 | 34 |
| 33 const char kPrivetContentTypePDF[] = "application/pdf"; | 35 const char kPrivetContentTypePDF[] = "application/pdf"; |
| 34 const char kPrivetContentTypePWGRaster[] = "image/pwg-raster"; | 36 const char kPrivetContentTypePWGRaster[] = "image/pwg-raster"; |
| 35 const char kPrivetContentTypeAny[] = "*/*"; | 37 const char kPrivetContentTypeAny[] = "*/*"; |
| 36 const char kPrivetContentTypeCJT[] = "application/json"; | 38 const char kPrivetContentTypeCJT[] = "application/json"; |
| 37 | 39 |
| 38 const char kPrivetStorageListPath[] = "/privet/storage/list"; | 40 const char kPrivetStorageListPath[] = "/privet/storage/list"; |
| 39 const char kPrivetStorageParamPathFormat[] = "path=%s"; | 41 const char kPrivetStorageParamPathFormat[] = "path=%s"; |
| 40 | 42 |
| 41 const char kPrivetCDDKeySupportedContentTypes[] = | |
| 42 "printer.supported_content_type"; | |
| 43 | |
| 44 const char kPrivetCDDKeyContentType[] = "content_type"; | |
| 45 | |
| 46 const char kPrivetKeyJobID[] = "job_id"; | 43 const char kPrivetKeyJobID[] = "job_id"; |
| 47 | 44 |
| 48 const int kPrivetCancelationTimeoutSeconds = 3; | 45 const int kPrivetCancelationTimeoutSeconds = 3; |
| 49 | 46 |
| 50 const int kPrivetLocalPrintMaxRetries = 2; | 47 const int kPrivetLocalPrintMaxRetries = 2; |
| 51 | 48 |
| 52 const int kPrivetLocalPrintDefaultTimeout = 5; | 49 const int kPrivetLocalPrintDefaultTimeout = 5; |
| 53 | 50 |
| 54 GURL CreatePrivetURL(const std::string& path) { | 51 GURL CreatePrivetURL(const std::string& path) { |
| 55 GURL url(kUrlPlaceHolder); | 52 GURL url(kUrlPlaceHolder); |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 | 373 |
| 377 void PrivetJSONOperationImpl::OnNeedPrivetToken( | 374 void PrivetJSONOperationImpl::OnNeedPrivetToken( |
| 378 PrivetURLFetcher* fetcher, | 375 PrivetURLFetcher* fetcher, |
| 379 const PrivetURLFetcher::TokenCallback& callback) { | 376 const PrivetURLFetcher::TokenCallback& callback) { |
| 380 privet_client_->RefreshPrivetToken(callback); | 377 privet_client_->RefreshPrivetToken(callback); |
| 381 } | 378 } |
| 382 | 379 |
| 383 PrivetLocalPrintOperationImpl::PrivetLocalPrintOperationImpl( | 380 PrivetLocalPrintOperationImpl::PrivetLocalPrintOperationImpl( |
| 384 PrivetHTTPClientImpl* privet_client, | 381 PrivetHTTPClientImpl* privet_client, |
| 385 PrivetLocalPrintOperation::Delegate* delegate) | 382 PrivetLocalPrintOperation::Delegate* delegate) |
| 386 : privet_client_(privet_client), delegate_(delegate), | 383 : privet_client_(privet_client), |
| 387 use_pdf_(false), has_capabilities_(false), has_extended_workflow_(false), | 384 delegate_(delegate), |
| 388 started_(false), offline_(false), invalid_job_retries_(0), | 385 use_pdf_(false), |
| 386 has_capabilities_(false), |
| 387 has_extended_workflow_(false), |
| 388 started_(false), |
| 389 offline_(false), |
| 390 dpi_(printing::kDefaultPdfDpi), |
| 391 invalid_job_retries_(0), |
| 389 weak_factory_(this) { | 392 weak_factory_(this) { |
| 390 } | 393 } |
| 391 | 394 |
| 392 PrivetLocalPrintOperationImpl::~PrivetLocalPrintOperationImpl() { | 395 PrivetLocalPrintOperationImpl::~PrivetLocalPrintOperationImpl() { |
| 393 } | 396 } |
| 394 | 397 |
| 395 void PrivetLocalPrintOperationImpl::Start() { | 398 void PrivetLocalPrintOperationImpl::Start() { |
| 396 DCHECK(!started_); | 399 DCHECK(!started_); |
| 397 | 400 |
| 398 // We need to get the /info response so we can know which APIs are available. | 401 // We need to get the /info response so we can know which APIs are available. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 StartInitialRequest(); | 438 StartInitialRequest(); |
| 436 } else { | 439 } else { |
| 437 delegate_->OnPrivetPrintingError(this, -1); | 440 delegate_->OnPrivetPrintingError(this, -1); |
| 438 } | 441 } |
| 439 } | 442 } |
| 440 | 443 |
| 441 void PrivetLocalPrintOperationImpl::StartInitialRequest() { | 444 void PrivetLocalPrintOperationImpl::StartInitialRequest() { |
| 442 if (has_capabilities_) { | 445 if (has_capabilities_) { |
| 443 GetCapabilities(); | 446 GetCapabilities(); |
| 444 } else { | 447 } else { |
| 445 // Since we have no capabiltties, the only reasonable format we can | 448 // Since we have no capabilities, the only reasonable format we can |
| 446 // request is PWG Raster. | 449 // request is PWG Raster. |
| 447 use_pdf_ = false; | 450 use_pdf_ = false; |
| 448 StartConvertToPWG(); | 451 StartConvertToPWG(); |
| 449 } | 452 } |
| 450 } | 453 } |
| 451 | 454 |
| 452 void PrivetLocalPrintOperationImpl::GetCapabilities() { | 455 void PrivetLocalPrintOperationImpl::GetCapabilities() { |
| 453 current_response_ = base::Bind( | 456 current_response_ = base::Bind( |
| 454 &PrivetLocalPrintOperationImpl::OnCapabilitiesResponse, | 457 &PrivetLocalPrintOperationImpl::OnCapabilitiesResponse, |
| 455 base::Unretained(this)); | 458 base::Unretained(this)); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 if (has_extended_workflow_ && !ticket_.empty() && jobid_.empty()) { | 530 if (has_extended_workflow_ && !ticket_.empty() && jobid_.empty()) { |
| 528 DoCreatejob(); | 531 DoCreatejob(); |
| 529 } else { | 532 } else { |
| 530 DoSubmitdoc(); | 533 DoSubmitdoc(); |
| 531 } | 534 } |
| 532 } | 535 } |
| 533 | 536 |
| 534 void PrivetLocalPrintOperationImpl::StartConvertToPWG() { | 537 void PrivetLocalPrintOperationImpl::StartConvertToPWG() { |
| 535 if (!pwg_raster_converter_) | 538 if (!pwg_raster_converter_) |
| 536 pwg_raster_converter_ = PWGRasterConverter::CreateDefault(); | 539 pwg_raster_converter_ = PWGRasterConverter::CreateDefault(); |
| 540 double scale = dpi_; |
| 541 scale /= printing::kPointsPerInch; |
| 542 // Make vertical rectangle to optimize streaming to printer. Fix orientation |
| 543 // by autorotate. |
| 544 gfx::Rect area(std::min(page_size_.width(), page_size_.height()) * scale, |
| 545 std::max(page_size_.width(), page_size_.height()) * scale); |
| 537 pwg_raster_converter_->Start( | 546 pwg_raster_converter_->Start( |
| 538 data_, | 547 data_, printing::PdfRenderSettings(area, dpi_, true), |
| 539 conversion_settings_, | |
| 540 base::Bind(&PrivetLocalPrintOperationImpl::OnPWGRasterConverted, | 548 base::Bind(&PrivetLocalPrintOperationImpl::OnPWGRasterConverted, |
| 541 base::Unretained(this))); | 549 base::Unretained(this))); |
| 542 } | 550 } |
| 543 | 551 |
| 544 void PrivetLocalPrintOperationImpl::OnCapabilitiesResponse( | 552 void PrivetLocalPrintOperationImpl::OnCapabilitiesResponse( |
| 545 bool has_error, | 553 bool has_error, |
| 546 const base::DictionaryValue* value) { | 554 const base::DictionaryValue* value) { |
| 547 if (has_error) { | 555 if (has_error) { |
| 548 delegate_->OnPrivetPrintingError(this, 200); | 556 delegate_->OnPrivetPrintingError(this, 200); |
| 549 return; | 557 return; |
| 550 } | 558 } |
| 551 | 559 |
| 552 const base::ListValue* supported_content_types; | 560 cloud_devices::CloudDeviceDescription description; |
| 561 if (!description.InitFromDictionary(make_scoped_ptr(value->DeepCopy()))) { |
| 562 delegate_->OnPrivetPrintingError(this, 200); |
| 563 return; |
| 564 } |
| 565 |
| 553 use_pdf_ = false; | 566 use_pdf_ = false; |
| 554 | 567 cloud_devices::printer::ContentTypesCapability content_types; |
| 555 if (value->GetList(kPrivetCDDKeySupportedContentTypes, | 568 if (content_types.LoadFrom(description)) { |
| 556 &supported_content_types)) { | 569 use_pdf_ = content_types.Contains(kPrivetContentTypePDF) || |
| 557 for (size_t i = 0; i < supported_content_types->GetSize(); i++) { | 570 content_types.Contains(kPrivetContentTypeAny); |
| 558 const base::DictionaryValue* content_type_value; | |
| 559 std::string content_type; | |
| 560 | |
| 561 if (supported_content_types->GetDictionary(i, &content_type_value) && | |
| 562 content_type_value->GetString(kPrivetCDDKeyContentType, | |
| 563 &content_type) && | |
| 564 (content_type == kPrivetContentTypePDF || | |
| 565 content_type == kPrivetContentTypeAny) ) { | |
| 566 use_pdf_ = true; | |
| 567 } | |
| 568 } | |
| 569 } | 571 } |
| 570 | 572 |
| 571 if (use_pdf_) { | 573 if (use_pdf_) { |
| 572 StartPrinting(); | 574 StartPrinting(); |
| 573 } else { | 575 } else { |
| 576 cloud_devices::printer::DpiCapability dpis; |
| 577 if (dpis.LoadFrom(description)) { |
| 578 dpi_ = std::max(dpis.GetDefault().horizontal, dpis.GetDefault().vertical); |
| 579 } |
| 574 StartConvertToPWG(); | 580 StartConvertToPWG(); |
| 575 } | 581 } |
| 576 } | 582 } |
| 577 | 583 |
| 578 void PrivetLocalPrintOperationImpl::OnSubmitdocResponse( | 584 void PrivetLocalPrintOperationImpl::OnSubmitdocResponse( |
| 579 bool has_error, | 585 bool has_error, |
| 580 const base::DictionaryValue* value) { | 586 const base::DictionaryValue* value) { |
| 581 std::string error; | 587 std::string error; |
| 582 // This error is only relevant in the case of extended workflow: | 588 // This error is only relevant in the case of extended workflow: |
| 583 // If the print job ID is invalid, retry createjob and submitdoc, | 589 // If the print job ID is invalid, retry createjob and submitdoc, |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 void PrivetLocalPrintOperationImpl::SetJobname(const std::string& jobname) { | 694 void PrivetLocalPrintOperationImpl::SetJobname(const std::string& jobname) { |
| 689 DCHECK(!started_); | 695 DCHECK(!started_); |
| 690 jobname_ = jobname; | 696 jobname_ = jobname; |
| 691 } | 697 } |
| 692 | 698 |
| 693 void PrivetLocalPrintOperationImpl::SetOffline(bool offline) { | 699 void PrivetLocalPrintOperationImpl::SetOffline(bool offline) { |
| 694 DCHECK(!started_); | 700 DCHECK(!started_); |
| 695 offline_ = offline; | 701 offline_ = offline; |
| 696 } | 702 } |
| 697 | 703 |
| 698 void PrivetLocalPrintOperationImpl::SetConversionSettings( | 704 void PrivetLocalPrintOperationImpl::SetPageSize(const gfx::Size& page_size) { |
| 699 const printing::PdfRenderSettings& conversion_settings) { | |
| 700 DCHECK(!started_); | 705 DCHECK(!started_); |
| 701 conversion_settings_ = conversion_settings; | 706 page_size_ = page_size; |
| 702 } | 707 } |
| 703 | 708 |
| 704 void PrivetLocalPrintOperationImpl::SetPWGRasterConverterForTesting( | 709 void PrivetLocalPrintOperationImpl::SetPWGRasterConverterForTesting( |
| 705 scoped_ptr<PWGRasterConverter> pwg_raster_converter) { | 710 scoped_ptr<PWGRasterConverter> pwg_raster_converter) { |
| 706 pwg_raster_converter_ = pwg_raster_converter.Pass(); | 711 pwg_raster_converter_ = pwg_raster_converter.Pass(); |
| 707 } | 712 } |
| 708 | 713 |
| 709 PrivetHTTPClientImpl::PrivetHTTPClientImpl( | 714 PrivetHTTPClientImpl::PrivetHTTPClientImpl( |
| 710 const std::string& name, | 715 const std::string& name, |
| 711 const net::HostPortPair& host_port, | 716 const net::HostPortPair& host_port, |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 814 TokenCallbackVector token_callbacks; | 819 TokenCallbackVector token_callbacks; |
| 815 token_callbacks_.swap(token_callbacks); | 820 token_callbacks_.swap(token_callbacks); |
| 816 | 821 |
| 817 for (TokenCallbackVector::iterator i = token_callbacks.begin(); | 822 for (TokenCallbackVector::iterator i = token_callbacks.begin(); |
| 818 i != token_callbacks.end(); i++) { | 823 i != token_callbacks.end(); i++) { |
| 819 i->Run(token); | 824 i->Run(token); |
| 820 } | 825 } |
| 821 } | 826 } |
| 822 | 827 |
| 823 } // namespace local_discovery | 828 } // namespace local_discovery |
| OLD | NEW |