Skip to content

Commit

Permalink
Tunnel PWGRasterConfig capability to the ticket and to the utility pr…
Browse files Browse the repository at this point in the history
…ocess

Parse the PWGRasterConfig capability for local printing, copy it to the ticket,
and tunnel a data structure based on it to the utility process.

BUG=354605

Review URL: https://codereview.chromium.org/211843004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@259938 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
noamsml@chromium.org committed Mar 27, 2014
1 parent a5f50b7 commit 35cf6cd
Show file tree
Hide file tree
Showing 9 changed files with 247 additions and 22 deletions.
70 changes: 67 additions & 3 deletions chrome/browser/local_discovery/privet_http_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@
#include "chrome/browser/local_discovery/privet_constants.h"
#include "components/cloud_devices/printer_description.h"
#include "net/base/url_util.h"
#include "printing/pwg_raster_settings.h"
#include "printing/units.h"
#include "ui/gfx/text_elider.h"
#include "url/gurl.h"

using namespace cloud_devices::printer;

namespace local_discovery {

namespace {
Expand Down Expand Up @@ -513,7 +516,7 @@ void PrivetLocalPrintOperationImpl::OnPrivetInfoDone(

void PrivetLocalPrintOperationImpl::StartInitialRequest() {
use_pdf_ = false;
cloud_devices::printer::ContentTypesCapability content_types;
ContentTypesCapability content_types;
if (content_types.LoadFrom(capabilities_)) {
use_pdf_ = content_types.Contains(kPrivetContentTypePDF) ||
content_types.Contains(kPrivetContentTypeAny);
Expand All @@ -522,7 +525,7 @@ void PrivetLocalPrintOperationImpl::StartInitialRequest() {
if (use_pdf_) {
StartPrinting();
} else {
cloud_devices::printer::DpiCapability dpis;
DpiCapability dpis;
if (dpis.LoadFrom(capabilities_)) {
dpi_ = std::max(dpis.GetDefault().horizontal, dpis.GetDefault().vertical);
}
Expand All @@ -535,6 +538,14 @@ void PrivetLocalPrintOperationImpl::DoCreatejob() {
&PrivetLocalPrintOperationImpl::OnCreatejobResponse,
base::Unretained(this));

// Add PWG raster settings to ticket if they are supplied by the printer.
PwgRasterConfigCapability raster_capability;
PwgRasterConfigTicketItem raster_ticket_item;
if (raster_capability.LoadFrom(capabilities_)) {
raster_ticket_item.set_value(raster_capability.value());
raster_ticket_item.SaveTo(&ticket_);
}

url_fetcher_= privet_client_->CreateURLFetcher(
CreatePrivetURL(kPrivetCreatejobPath), net::URLFetcher::POST, this);
url_fetcher_->SetUploadData(kPrivetContentTypeCJT, ticket_.ToString());
Expand Down Expand Up @@ -605,17 +616,70 @@ void PrivetLocalPrintOperationImpl::StartPrinting() {
}
}

void PrivetLocalPrintOperationImpl::FillPwgRasterSettings(
printing::PwgRasterSettings* transform_settings) {
PwgRasterConfigCapability raster_capability;
// If the raster capability fails to load, raster_capability will contain
// the default value.
raster_capability.LoadFrom(capabilities_);

DuplexTicketItem duplex_item;
DuplexType duplex_value = NO_DUPLEX;

DocumentSheetBack document_sheet_back =
raster_capability.value().document_sheet_back;

if (duplex_item.LoadFrom(ticket_)) {
duplex_value = duplex_item.value();
}

transform_settings->odd_page_transform = printing::TRANSFORM_NORMAL;
switch (duplex_value) {
case NO_DUPLEX:
transform_settings->odd_page_transform = printing::TRANSFORM_NORMAL;
break;
case LONG_EDGE:
if (document_sheet_back == ROTATED) {
transform_settings->odd_page_transform = printing::TRANSFORM_ROTATE_180;
} else if (document_sheet_back == FLIPPED) {
transform_settings->odd_page_transform =
printing::TRANSFORM_FLIP_VERTICAL;
}
break;
case SHORT_EDGE:
if (document_sheet_back == MANUAL_TUMBLE) {
transform_settings->odd_page_transform = printing::TRANSFORM_ROTATE_180;
} else if (document_sheet_back == FLIPPED) {
transform_settings->odd_page_transform =
printing::TRANSFORM_FLIP_HORIZONTAL;
}
}

transform_settings->rotate_all_pages =
raster_capability.value().rotate_all_pages;

transform_settings->reverse_page_order =
raster_capability.value().reverse_order_streaming;
}

void PrivetLocalPrintOperationImpl::StartConvertToPWG() {
printing::PwgRasterSettings transform_settings;

FillPwgRasterSettings(&transform_settings);

if (!pwg_raster_converter_)
pwg_raster_converter_ = PWGRasterConverter::CreateDefault();

double scale = dpi_;
scale /= printing::kPointsPerInch;
// Make vertical rectangle to optimize streaming to printer. Fix orientation
// by autorotate.
gfx::Rect area(std::min(page_size_.width(), page_size_.height()) * scale,
std::max(page_size_.width(), page_size_.height()) * scale);
pwg_raster_converter_->Start(
data_, printing::PdfRenderSettings(area, dpi_, true),
data_,
printing::PdfRenderSettings(area, dpi_, true),
transform_settings,
base::Bind(&PrivetLocalPrintOperationImpl::OnPWGRasterConverted,
base::Unretained(this)));
}
Expand Down
5 changes: 5 additions & 0 deletions chrome/browser/local_discovery/privet_http_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
#include "components/cloud_devices/cloud_device_description.h"
#include "printing/pdf_render_settings.h"

namespace printing {
struct PwgRasterSettings;
};

namespace local_discovery {

class PrivetHTTPClientImpl;
Expand Down Expand Up @@ -247,6 +251,7 @@ class PrivetLocalPrintOperationImpl
void OnCreatejobResponse(bool has_error,
const base::DictionaryValue* value);
void OnPWGRasterConverted(bool success, const base::FilePath& pwg_file_path);
void FillPwgRasterSettings(printing::PwgRasterSettings* transfrom_settings);

PrivetHTTPClientImpl* privet_client_;
PrivetLocalPrintOperation::Delegate* delegate_;
Expand Down
89 changes: 88 additions & 1 deletion chrome/browser/local_discovery/privet_http_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "net/base/net_errors.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_request_test_util.h"
#include "printing/pwg_raster_settings.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

Expand Down Expand Up @@ -189,6 +190,37 @@ const char kSampleEmptyJSONResponse[] = "{}";

const char kSampleCJT[] = "{ \"version\" : \"1.0\" }";

const char kSampleCapabilitiesResponsePWGSettings[] =
"{"
"\"version\" : \"1.0\","
"\"printer\" : {"
" \"pwg_raster_config\" : {"
" \"document_sheet_back\" : \"MANUAL_TUMBLE\","
" \"reverse_order_streaming\": true"
" },"
" \"supported_content_type\" : ["
" { \"content_type\" : \"image/pwg-raster\" }"
" ]"
"}"
"}";

const char kSampleCJTDuplex[] =
"{"
"\"version\" : \"1.0\","
"\"print\": { \"duplex\": {\"type\": \"SHORT_EDGE\"} }"
"}";

const char kSampleCJTDuplexPWGSettings[] =
"{"
"\"version\" : \"1.0\","
"\"print\": {"
" \"pwg_raster_config\" : {"
" \"document_sheet_back\" : \"MANUAL_TUMBLE\","
" \"reverse_order_streaming\": true"
" },"
" \"duplex\": {\"type\": \"SHORT_EDGE\"} }"
"}";

// Return the representation of the given JSON that would be outputted by
// JSONWriter. This ensures the same JSON values are represented by the same
// string.
Expand Down Expand Up @@ -423,10 +455,19 @@ class FakePWGRasterConverter : public PWGRasterConverter {

virtual void Start(base::RefCountedMemory* data,
const printing::PdfRenderSettings& conversion_settings,
const printing::PwgRasterSettings& bitmap_settings,
const ResultCallback& callback) OVERRIDE {
bitmap_settings_ = bitmap_settings;
std::string data_str(data->front_as<char>(), data->size());
callback.Run(true, base::FilePath().AppendASCII(data_str + "test.pdf"));
}

const printing::PwgRasterSettings& bitmap_settings() {
return bitmap_settings_;
}

private:
printing::PwgRasterSettings bitmap_settings_;
};

TEST_F(PrivetHTTPTest, CreatePrivetStorageList) {
Expand Down Expand Up @@ -776,8 +817,11 @@ class PrivetLocalPrintTest : public PrivetHTTPTest {
local_print_operation_ = privet_client_->CreateLocalPrintOperation(
&local_print_delegate_);

scoped_ptr<FakePWGRasterConverter> pwg_converter(
new FakePWGRasterConverter);
pwg_converter_ = pwg_converter.get();
local_print_operation_->SetPWGRasterConverterForTesting(
scoped_ptr<PWGRasterConverter>(new FakePWGRasterConverter));
pwg_converter.PassAs<PWGRasterConverter>());
}

scoped_refptr<base::RefCountedBytes> RefCountedBytesFromString(
Expand All @@ -791,6 +835,7 @@ class PrivetLocalPrintTest : public PrivetHTTPTest {
protected:
scoped_ptr<PrivetLocalPrintOperation> local_print_operation_;
StrictMock<MockLocalPrintDelegate> local_print_delegate_;
FakePWGRasterConverter* pwg_converter_;
};

TEST_F(PrivetLocalPrintTest, SuccessfulLocalPrint) {
Expand Down Expand Up @@ -870,6 +915,48 @@ TEST_F(PrivetLocalPrintTest, SuccessfulPWGLocalPrint) {
"&job_name=Sample+job+name"),
base::FilePath(FILE_PATH_LITERAL("path/to/test.pdf")),
kSampleLocalPrintResponse));

EXPECT_EQ(printing::TRANSFORM_NORMAL,
pwg_converter_->bitmap_settings().odd_page_transform);
EXPECT_FALSE(pwg_converter_->bitmap_settings().rotate_all_pages);
EXPECT_FALSE(pwg_converter_->bitmap_settings().reverse_page_order);
};

TEST_F(PrivetLocalPrintTest, SuccessfulPWGLocalPrintDuplex) {
local_print_operation_->SetUsername("sample@gmail.com");
local_print_operation_->SetJobname("Sample job name");
local_print_operation_->SetData(RefCountedBytesFromString("path/to/"));
local_print_operation_->SetTicket(kSampleCJTDuplex);
local_print_operation_->SetCapabilities(
kSampleCapabilitiesResponsePWGSettings);
local_print_operation_->Start();

EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
kSampleInfoResponseWithCreatejob));

EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
kSampleInfoResponse));

EXPECT_TRUE(SuccessfulResponseToURLAndJSONData(
GURL("http://10.0.0.8:6006/privet/printer/createjob"),
kSampleCJTDuplexPWGSettings,
kSampleCreatejobResponse));

EXPECT_CALL(local_print_delegate_, OnPrivetPrintingDoneInternal());

// TODO(noamsml): Is encoding spaces as pluses standard?
EXPECT_TRUE(SuccessfulResponseToURLAndFilePath(
GURL(
"http://10.0.0.8:6006/privet/printer/submitdoc?"
"client_name=Chrome&user_name=sample%40gmail.com"
"&job_name=Sample+job+name&job_id=1234"),
base::FilePath(FILE_PATH_LITERAL("path/to/test.pdf")),
kSampleLocalPrintResponse));

EXPECT_EQ(printing::TRANSFORM_ROTATE_180,
pwg_converter_->bitmap_settings().odd_page_transform);
EXPECT_FALSE(pwg_converter_->bitmap_settings().rotate_all_pages);
EXPECT_TRUE(pwg_converter_->bitmap_settings().reverse_page_order);
};

TEST_F(PrivetLocalPrintTest, SuccessfulLocalPrintWithCreatejob) {
Expand Down
25 changes: 16 additions & 9 deletions chrome/browser/local_discovery/pwg_raster_converter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ bool FileHandlers::IsValid() {
class PwgUtilityProcessHostClient : public content::UtilityProcessHostClient {
public:
explicit PwgUtilityProcessHostClient(
const printing::PdfRenderSettings& settings);
const printing::PdfRenderSettings& settings,
const printing::PwgRasterSettings& bitmap_settings);

void Convert(base::RefCountedMemory* data,
const PWGRasterConverter::ResultCallback& callback);
Expand All @@ -134,15 +135,17 @@ class PwgUtilityProcessHostClient : public content::UtilityProcessHostClient {

scoped_ptr<FileHandlers> files_;
printing::PdfRenderSettings settings_;
printing::PwgRasterSettings bitmap_settings_;
PWGRasterConverter::ResultCallback callback_;
base::WeakPtr<content::UtilityProcessHost> utility_process_host_;

DISALLOW_COPY_AND_ASSIGN(PwgUtilityProcessHostClient);
};

PwgUtilityProcessHostClient::PwgUtilityProcessHostClient(
const printing::PdfRenderSettings& settings) : settings_(settings) {
}
const printing::PdfRenderSettings& settings,
const printing::PwgRasterSettings& bitmap_settings)
: settings_(settings), bitmap_settings_(bitmap_settings) {}

PwgUtilityProcessHostClient::~PwgUtilityProcessHostClient() {
// Delete temp directory.
Expand Down Expand Up @@ -189,11 +192,11 @@ void PwgUtilityProcessHostClient::OnProcessStarted() {
}

base::ProcessHandle process = utility_process_host_->GetData().handle;
utility_process_host_->Send(
new ChromeUtilityMsg_RenderPDFPagesToPWGRaster(
files_->GetPdfForProcess(process),
settings_,
files_->GetPwgForProcess(process)));
utility_process_host_->Send(new ChromeUtilityMsg_RenderPDFPagesToPWGRaster(
files_->GetPdfForProcess(process),
settings_,
bitmap_settings_,
files_->GetPwgForProcess(process)));
utility_process_host_.reset();
}

Expand Down Expand Up @@ -252,7 +255,9 @@ class PWGRasterConverterImpl : public PWGRasterConverter {

virtual void Start(base::RefCountedMemory* data,
const printing::PdfRenderSettings& conversion_settings,
const printing::PwgRasterSettings& bitmap_settings,
const ResultCallback& callback) OVERRIDE;

private:
scoped_refptr<PwgUtilityProcessHostClient> utility_client_;
base::CancelableCallback<ResultCallback::RunType> callback_;
Expand All @@ -269,11 +274,13 @@ PWGRasterConverterImpl::~PWGRasterConverterImpl() {
void PWGRasterConverterImpl::Start(
base::RefCountedMemory* data,
const printing::PdfRenderSettings& conversion_settings,
const printing::PwgRasterSettings& bitmap_settings,
const ResultCallback& callback) {
// Rebind cancelable callback to avoid calling callback if
// PWGRasterConverterImpl is destroyed.
callback_.Reset(callback);
utility_client_ = new PwgUtilityProcessHostClient(conversion_settings);
utility_client_ =
new PwgUtilityProcessHostClient(conversion_settings, bitmap_settings);
utility_client_->Convert(data, callback_.callback());
}

Expand Down
2 changes: 2 additions & 0 deletions chrome/browser/local_discovery/pwg_raster_converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class Size;

namespace printing {
class PdfRenderSettings;
struct PwgRasterSettings;
}

namespace local_discovery {
Expand All @@ -37,6 +38,7 @@ class PWGRasterConverter {

virtual void Start(base::RefCountedMemory* data,
const printing::PdfRenderSettings& conversion_settings,
const printing::PwgRasterSettings& bitmap_settings,
const ResultCallback& callback) = 0;
};

Expand Down
Loading

0 comments on commit 35cf6cd

Please sign in to comment.