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 |