Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(328)

Side by Side Diff: chrome/service/cloud_print/print_system_win.cc

Issue 1920793005: Merge to M51: Cloud Print Proxy: Delete print jobs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2704
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/service/cloud_print/print_system.h" 5 #include "chrome/service/cloud_print/print_system.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/files/file_util.h" 8 #include "base/files/file_util.h"
9 #include "base/json/json_writer.h" 9 #include "base/json/json_writer.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
(...skipping 16 matching lines...) Expand all
27 #include "printing/emf_win.h" 27 #include "printing/emf_win.h"
28 #include "printing/page_range.h" 28 #include "printing/page_range.h"
29 #include "printing/pdf_render_settings.h" 29 #include "printing/pdf_render_settings.h"
30 #include "printing/printing_utils.h" 30 #include "printing/printing_utils.h"
31 #include "ui/gfx/geometry/rect.h" 31 #include "ui/gfx/geometry/rect.h"
32 32
33 namespace cloud_print { 33 namespace cloud_print {
34 34
35 namespace { 35 namespace {
36 36
37 bool CurrentlyOnServiceIOThread() {
38 return g_service_process->io_task_runner()->BelongsToCurrentThread();
39 }
40
41 bool PostIOThreadTask(const tracked_objects::Location& from_here,
42 const base::Closure& task) {
43 return g_service_process->io_task_runner()->PostTask(from_here, task);
44 }
45
37 class PrintSystemWatcherWin : public base::win::ObjectWatcher::Delegate { 46 class PrintSystemWatcherWin : public base::win::ObjectWatcher::Delegate {
38 public: 47 public:
39 PrintSystemWatcherWin() 48 PrintSystemWatcherWin()
40 : delegate_(NULL) { 49 : delegate_(NULL) {
41 } 50 }
42 ~PrintSystemWatcherWin() override { Stop(); } 51 ~PrintSystemWatcherWin() override { Stop(); }
43 52
44 class Delegate { 53 class Delegate {
45 public: 54 public:
46 virtual ~Delegate() {} 55 virtual ~Delegate() {}
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 const base::FilePath& print_data_file_path, 261 const base::FilePath& print_data_file_path,
253 const std::string& print_data_mime_type, 262 const std::string& print_data_mime_type,
254 const std::string& printer_name, 263 const std::string& printer_name,
255 const std::string& job_title, 264 const std::string& job_title,
256 JobSpooler::Delegate* delegate) { 265 JobSpooler::Delegate* delegate) {
257 if (delegate_) { 266 if (delegate_) {
258 // We are already in the process of printing. 267 // We are already in the process of printing.
259 NOTREACHED(); 268 NOTREACHED();
260 return false; 269 return false;
261 } 270 }
262 base::string16 printer_wide = base::UTF8ToWide(printer_name); 271
263 // We only support PDF and XPS documents for now. 272 // We only support PDF and XPS documents for now.
264 if (print_data_mime_type == kContentTypePDF) { 273 if (print_data_mime_type == kContentTypePDF) {
265 scoped_ptr<DEVMODE, base::FreeDeleter> dev_mode; 274 base::string16 printer_wide = base::UTF8ToWide(printer_name);
275 std::unique_ptr<DEVMODE, base::FreeDeleter> dev_mode;
266 if (print_ticket_mime_type == kContentTypeJSON) { 276 if (print_ticket_mime_type == kContentTypeJSON) {
267 dev_mode = CjtToDevMode(printer_wide, print_ticket); 277 dev_mode = CjtToDevMode(printer_wide, print_ticket);
268 } else { 278 } else {
269 DCHECK(print_ticket_mime_type == kContentTypeXML); 279 DCHECK_EQ(kContentTypeXML, print_ticket_mime_type);
270 dev_mode = printing::XpsTicketToDevMode(printer_wide, print_ticket); 280 dev_mode = printing::XpsTicketToDevMode(printer_wide, print_ticket);
271 } 281 }
272 282
273 if (!dev_mode) { 283 if (!dev_mode) {
274 NOTREACHED(); 284 NOTREACHED();
275 return false; 285 return false;
276 } 286 }
277 287
278 HDC dc = CreateDC(L"WINSPOOL", printer_wide.c_str(), NULL, 288 HDC dc = CreateDC(L"WINSPOOL", printer_wide.c_str(), NULL,
279 dev_mode.get()); 289 dev_mode.get());
280 if (!dc) { 290 if (!dc) {
281 NOTREACHED(); 291 NOTREACHED();
282 return false; 292 return false;
283 } 293 }
284 DOCINFO di = {0}; 294 DOCINFO di = {0};
285 di.cbSize = sizeof(DOCINFO); 295 di.cbSize = sizeof(DOCINFO);
286 base::string16 doc_name = base::UTF8ToUTF16(job_title); 296 base::string16 doc_name = base::UTF8ToUTF16(job_title);
287 DCHECK(printing::SimplifyDocumentTitle(doc_name) == doc_name); 297 DCHECK(printing::SimplifyDocumentTitle(doc_name) == doc_name);
288 di.lpszDocName = doc_name.c_str(); 298 di.lpszDocName = doc_name.c_str();
289 job_id_ = StartDoc(dc, &di); 299 job_id_ = StartDoc(dc, &di);
290 if (job_id_ <= 0) 300 if (job_id_ <= 0)
291 return false; 301 return false;
292 302
293 printer_dc_.Set(dc); 303 printer_dc_.Set(dc);
294 saved_dc_ = SaveDC(printer_dc_.Get()); 304 saved_dc_ = SaveDC(printer_dc_.Get());
295 print_data_file_path_ = print_data_file_path;
296 delegate_ = delegate; 305 delegate_ = delegate;
297 RenderPDFPages(); 306 RenderPDFPages(print_data_file_path);
298 } else if (print_data_mime_type == kContentTypeXPS) { 307 return true;
308 }
309
310 if (print_data_mime_type == kContentTypeXPS) {
299 DCHECK(print_ticket_mime_type == kContentTypeXML); 311 DCHECK(print_ticket_mime_type == kContentTypeXML);
300 bool ret = PrintXPSDocument(printer_name, 312 bool ret = PrintXPSDocument(printer_name,
301 job_title, 313 job_title,
302 print_data_file_path, 314 print_data_file_path,
303 print_ticket); 315 print_ticket);
304 if (ret) 316 if (ret)
305 delegate_ = delegate; 317 delegate_ = delegate;
306 return ret; 318 return ret;
307 } else {
308 NOTREACHED();
309 return false;
310 } 319 }
311 return true; 320
321 NOTREACHED();
322 return false;
312 } 323 }
313 324
314 void PreparePageDCForPrinting(HDC, float scale_factor) { 325 void PreparePageDCForPrinting(HDC, float scale_factor) {
315 SetGraphicsMode(printer_dc_.Get(), GM_ADVANCED); 326 SetGraphicsMode(printer_dc_.Get(), GM_ADVANCED);
316 // Setup the matrix to translate and scale to the right place. Take in 327 // Setup the matrix to translate and scale to the right place. Take in
317 // account the scale factor. 328 // account the scale factor.
318 // Note that the printing output is relative to printable area of 329 // Note that the printing output is relative to printable area of
319 // the page. That is 0,0 is offset by PHYSICALOFFSETX/Y from the page. 330 // the page. That is 0,0 is offset by PHYSICALOFFSETX/Y from the page.
320 int offset_x = ::GetDeviceCaps(printer_dc_.Get(), PHYSICALOFFSETX); 331 int offset_x = ::GetDeviceCaps(printer_dc_.Get(), PHYSICALOFFSETX);
321 int offset_y = ::GetDeviceCaps(printer_dc_.Get(), PHYSICALOFFSETY); 332 int offset_y = ::GetDeviceCaps(printer_dc_.Get(), PHYSICALOFFSETY);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 RestoreDC(printer_dc_.Get(), saved_dc_); 411 RestoreDC(printer_dc_.Get(), saved_dc_);
401 EndDoc(printer_dc_.Get()); 412 EndDoc(printer_dc_.Get());
402 if (success) { 413 if (success) {
403 delegate_->OnJobSpoolSucceeded(job_id_); 414 delegate_->OnJobSpoolSucceeded(job_id_);
404 } else { 415 } else {
405 delegate_->OnJobSpoolFailed(); 416 delegate_->OnJobSpoolFailed();
406 } 417 }
407 delegate_ = NULL; 418 delegate_ = NULL;
408 } 419 }
409 420
410 void RenderPDFPages() { 421 void RenderPDFPages(const base::FilePath& pdf_path) {
411 int printer_dpi = ::GetDeviceCaps(printer_dc_.Get(), LOGPIXELSX); 422 int printer_dpi = ::GetDeviceCaps(printer_dc_.Get(), LOGPIXELSX);
412 int dc_width = GetDeviceCaps(printer_dc_.Get(), PHYSICALWIDTH); 423 int dc_width = GetDeviceCaps(printer_dc_.Get(), PHYSICALWIDTH);
413 int dc_height = GetDeviceCaps(printer_dc_.Get(), PHYSICALHEIGHT); 424 int dc_height = GetDeviceCaps(printer_dc_.Get(), PHYSICALHEIGHT);
414 gfx::Rect render_area(0, 0, dc_width, dc_height); 425 gfx::Rect render_area(0, 0, dc_width, dc_height);
415 g_service_process->io_task_runner()->PostTask( 426 PostIOThreadTask(FROM_HERE,
416 FROM_HERE, 427 base::Bind(&JobSpoolerWin::Core::RenderPDFPagesInSandbox,
417 base::Bind(&JobSpoolerWin::Core::RenderPDFPagesInSandbox, this, 428 this, pdf_path, render_area, printer_dpi,
418 print_data_file_path_, render_area, printer_dpi, 429 base::ThreadTaskRunnerHandle::Get()));
419 base::ThreadTaskRunnerHandle::Get()));
420 } 430 }
421 431
422 // Called on the service process IO thread.
423 void RenderPDFPagesInSandbox( 432 void RenderPDFPagesInSandbox(
424 const base::FilePath& pdf_path, 433 const base::FilePath& pdf_path,
425 const gfx::Rect& render_area, 434 const gfx::Rect& render_area,
426 int render_dpi, 435 int render_dpi,
427 const scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner) { 436 const scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner) {
428 DCHECK(g_service_process->io_task_runner()->BelongsToCurrentThread()); 437 DCHECK(CurrentlyOnServiceIOThread());
429 scoped_ptr<ServiceUtilityProcessHost> utility_host( 438 std::unique_ptr<ServiceUtilityProcessHost> utility_host(
430 new ServiceUtilityProcessHost(this, client_task_runner.get())); 439 new ServiceUtilityProcessHost(this, client_task_runner.get()));
431 // TODO(gene): For now we disabling autorotation for CloudPrinting. 440 // TODO(gene): For now we disabling autorotation for CloudPrinting.
432 // Landscape/Portrait setting is passed in the print ticket and 441 // Landscape/Portrait setting is passed in the print ticket and
433 // server is generating portrait PDF always. 442 // server is generating portrait PDF always.
434 // We should enable autorotation once server will be able to generate 443 // We should enable autorotation once server will be able to generate
435 // PDF that matches paper size and orientation. 444 // PDF that matches paper size and orientation.
436 if (utility_host->StartRenderPDFPagesToMetafile( 445 if (utility_host->StartRenderPDFPagesToMetafile(
437 pdf_path, 446 pdf_path,
438 printing::PdfRenderSettings(render_area, render_dpi, false))) { 447 printing::PdfRenderSettings(render_area, render_dpi, false))) {
439 // The object will self-destruct when the child process dies. 448 // The object will self-destruct when the child process dies.
440 ignore_result(utility_host.release()); 449 ignore_result(utility_host.release());
441 } else { 450 } else {
442 client_task_runner->PostTask( 451 client_task_runner->PostTask(
443 FROM_HERE, base::Bind(&Core::PrintJobDone, this, false)); 452 FROM_HERE, base::Bind(&Core::PrintJobDone, this, false));
444 } 453 }
445 } 454 }
446 455
447 bool PrintXPSDocument(const std::string& printer_name, 456 bool PrintXPSDocument(const std::string& printer_name,
448 const std::string& job_title, 457 const std::string& job_title,
449 const base::FilePath& print_data_file_path, 458 const base::FilePath& xps_path,
450 const std::string& print_ticket) { 459 const std::string& print_ticket) {
460 base::File xps_file(xps_path, base::File::FLAG_OPEN |
461 base::File::FLAG_READ |
462 base::File::FLAG_DELETE_ON_CLOSE);
451 if (!printing::XPSPrintModule::Init()) 463 if (!printing::XPSPrintModule::Init())
452 return false; 464 return false;
453 465
454 job_progress_event_.Set(CreateEvent(NULL, TRUE, FALSE, NULL)); 466 job_progress_event_.Set(CreateEvent(nullptr, TRUE, FALSE, nullptr));
455 if (!job_progress_event_.Get()) 467 if (!job_progress_event_.Get())
456 return false; 468 return false;
457 469
458 PrintJobCanceler job_canceler(&xps_print_job_); 470 PrintJobCanceler job_canceler(&xps_print_job_);
459 base::win::ScopedComPtr<IXpsPrintJobStream> doc_stream; 471 base::win::ScopedComPtr<IXpsPrintJobStream> doc_stream;
460 base::win::ScopedComPtr<IXpsPrintJobStream> print_ticket_stream; 472 base::win::ScopedComPtr<IXpsPrintJobStream> print_ticket_stream;
461 if (FAILED(printing::XPSPrintModule::StartXpsPrintJob( 473 if (FAILED(printing::XPSPrintModule::StartXpsPrintJob(
462 base::UTF8ToWide(printer_name).c_str(), 474 base::UTF8ToWide(printer_name).c_str(),
463 base::UTF8ToWide(job_title).c_str(), 475 base::UTF8ToWide(job_title).c_str(), nullptr,
464 NULL, job_progress_event_.Get(), NULL, NULL, NULL, 476 job_progress_event_.Get(), nullptr, nullptr, 0,
465 xps_print_job_.Receive(), doc_stream.Receive(), 477 xps_print_job_.Receive(), doc_stream.Receive(),
466 print_ticket_stream.Receive()))) 478 print_ticket_stream.Receive()))) {
467 return false; 479 return false;
480 }
468 481
469 ULONG print_bytes_written = 0; 482 ULONG print_bytes_written = 0;
470 if (FAILED(print_ticket_stream->Write(print_ticket.c_str(), 483 if (FAILED(print_ticket_stream->Write(print_ticket.c_str(),
471 print_ticket.length(), 484 print_ticket.length(),
472 &print_bytes_written))) 485 &print_bytes_written))) {
473 return false; 486 return false;
487 }
474 DCHECK_EQ(print_ticket.length(), print_bytes_written); 488 DCHECK_EQ(print_ticket.length(), print_bytes_written);
475 if (FAILED(print_ticket_stream->Close())) 489 if (FAILED(print_ticket_stream->Close()))
476 return false; 490 return false;
477 491
478 std::string document_data; 492 int64_t file_size = xps_file.GetLength();
479 base::ReadFileToString(print_data_file_path, &document_data); 493 if (file_size <= 0)
494 return false;
495
496 std::unique_ptr<char[]> document_data(new char[file_size]);
497 int bytes_read = xps_file.Read(0, document_data.get(), file_size);
498 if (bytes_read != file_size)
499 return false;
500
480 ULONG doc_bytes_written = 0; 501 ULONG doc_bytes_written = 0;
481 if (FAILED(doc_stream->Write(document_data.c_str(), 502 if (FAILED(doc_stream->Write(document_data.get(), file_size,
482 document_data.length(), 503 &doc_bytes_written))) {
483 &doc_bytes_written)))
484 return false; 504 return false;
485 DCHECK_EQ(document_data.length(), doc_bytes_written); 505 }
506 DCHECK_EQ(file_size, doc_bytes_written);
486 if (FAILED(doc_stream->Close())) 507 if (FAILED(doc_stream->Close()))
487 return false; 508 return false;
488 509
489 job_progress_watcher_.StartWatchingOnce( 510 job_progress_watcher_.StartWatchingOnce(job_progress_event_.Get(), this);
490 job_progress_event_.Get(), this);
491 job_canceler.reset(); 511 job_canceler.reset();
492 return true; 512 return true;
493 } 513 }
494 514
495 PlatformJobId job_id_; 515 PlatformJobId job_id_;
496 PrintSystem::JobSpooler::Delegate* delegate_; 516 PrintSystem::JobSpooler::Delegate* delegate_;
497 int saved_dc_; 517 int saved_dc_;
498 base::win::ScopedCreateDC printer_dc_; 518 base::win::ScopedCreateDC printer_dc_;
499 base::FilePath print_data_file_path_;
500 base::win::ScopedHandle job_progress_event_; 519 base::win::ScopedHandle job_progress_event_;
501 base::win::ObjectWatcher job_progress_watcher_; 520 base::win::ObjectWatcher job_progress_watcher_;
502 base::win::ScopedComPtr<IXpsPrintJob> xps_print_job_; 521 base::win::ScopedComPtr<IXpsPrintJob> xps_print_job_;
503 522
504 DISALLOW_COPY_AND_ASSIGN(Core); 523 DISALLOW_COPY_AND_ASSIGN(Core);
505 }; 524 };
506 scoped_refptr<Core> core_; 525 scoped_refptr<Core> core_;
507 526
508 DISALLOW_COPY_AND_ASSIGN(JobSpoolerWin); 527 DISALLOW_COPY_AND_ASSIGN(JobSpoolerWin);
509 }; 528 };
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 *description, base::JSONWriter::OPTIONS_PRETTY_PRINT, 566 *description, base::JSONWriter::OPTIONS_PRETTY_PRINT,
548 &printer_info.printer_capabilities); 567 &printer_info.printer_capabilities);
549 } 568 }
550 } 569 }
551 callback_.Run(succeeded, printer_name, printer_info); 570 callback_.Run(succeeded, printer_name, printer_info);
552 callback_.Reset(); 571 callback_.Reset();
553 Release(); 572 Release();
554 } 573 }
555 574
556 void StartGetPrinterCapsAndDefaults() { 575 void StartGetPrinterCapsAndDefaults() {
557 g_service_process->io_task_runner()->PostTask( 576 PostIOThreadTask(
558 FROM_HERE, 577 FROM_HERE,
559 base::Bind(&PrinterCapsHandler::GetPrinterCapsAndDefaultsImpl, this, 578 base::Bind(&PrinterCapsHandler::GetPrinterCapsAndDefaultsImpl, this,
560 base::ThreadTaskRunnerHandle::Get())); 579 base::ThreadTaskRunnerHandle::Get()));
561 } 580 }
562 581
563 void StartGetPrinterSemanticCapsAndDefaults() { 582 void StartGetPrinterSemanticCapsAndDefaults() {
564 g_service_process->io_task_runner()->PostTask( 583 PostIOThreadTask(
565 FROM_HERE, 584 FROM_HERE,
566 base::Bind(&PrinterCapsHandler::GetPrinterSemanticCapsAndDefaultsImpl, 585 base::Bind(&PrinterCapsHandler::GetPrinterSemanticCapsAndDefaultsImpl,
567 this, base::ThreadTaskRunnerHandle::Get())); 586 this, base::ThreadTaskRunnerHandle::Get()));
568 } 587 }
569 588
570 private: 589 private:
571 ~PrinterCapsHandler() override {} 590 ~PrinterCapsHandler() override {}
572 591
573 void GetPrinterCapsAndDefaultsImpl( 592 void GetPrinterCapsAndDefaultsImpl(
574 const scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner) { 593 const scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner) {
575 DCHECK(g_service_process->io_task_runner()->BelongsToCurrentThread()); 594 DCHECK(CurrentlyOnServiceIOThread());
576 scoped_ptr<ServiceUtilityProcessHost> utility_host( 595 std::unique_ptr<ServiceUtilityProcessHost> utility_host(
577 new ServiceUtilityProcessHost(this, client_task_runner.get())); 596 new ServiceUtilityProcessHost(this, client_task_runner.get()));
578 if (utility_host->StartGetPrinterCapsAndDefaults(printer_name_)) { 597 if (utility_host->StartGetPrinterCapsAndDefaults(printer_name_)) {
579 // The object will self-destruct when the child process dies. 598 // The object will self-destruct when the child process dies.
580 ignore_result(utility_host.release()); 599 ignore_result(utility_host.release());
581 } else { 600 } else {
582 client_task_runner->PostTask( 601 client_task_runner->PostTask(
583 FROM_HERE, base::Bind(&PrinterCapsHandler::OnChildDied, this)); 602 FROM_HERE, base::Bind(&PrinterCapsHandler::OnChildDied, this));
584 } 603 }
585 } 604 }
586 605
587 void GetPrinterSemanticCapsAndDefaultsImpl( 606 void GetPrinterSemanticCapsAndDefaultsImpl(
588 const scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner) { 607 const scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner) {
589 DCHECK(g_service_process->io_task_runner()->BelongsToCurrentThread()); 608 DCHECK(CurrentlyOnServiceIOThread());
590 scoped_ptr<ServiceUtilityProcessHost> utility_host( 609 std::unique_ptr<ServiceUtilityProcessHost> utility_host(
591 new ServiceUtilityProcessHost(this, client_task_runner.get())); 610 new ServiceUtilityProcessHost(this, client_task_runner.get()));
592 if (utility_host->StartGetPrinterSemanticCapsAndDefaults(printer_name_)) { 611 if (utility_host->StartGetPrinterSemanticCapsAndDefaults(printer_name_)) {
593 // The object will self-destruct when the child process dies. 612 // The object will self-destruct when the child process dies.
594 ignore_result(utility_host.release()); 613 ignore_result(utility_host.release());
595 } else { 614 } else {
596 client_task_runner->PostTask( 615 client_task_runner->PostTask(
597 FROM_HERE, base::Bind(&PrinterCapsHandler::OnChildDied, this)); 616 FROM_HERE, base::Bind(&PrinterCapsHandler::OnChildDied, this));
598 } 617 }
599 } 618 }
600 619
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 } 831 }
813 832
814 } // namespace 833 } // namespace
815 834
816 scoped_refptr<PrintSystem> PrintSystem::CreateInstance( 835 scoped_refptr<PrintSystem> PrintSystem::CreateInstance(
817 const base::DictionaryValue* print_system_settings) { 836 const base::DictionaryValue* print_system_settings) {
818 return new PrintSystemWin; 837 return new PrintSystemWin;
819 } 838 }
820 839
821 } // namespace cloud_print 840 } // namespace cloud_print
OLDNEW
« no previous file with comments | « chrome/service/cloud_print/print_system_cups.cc ('k') | chrome/service/cloud_print/printer_job_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698