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

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

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