Chromium Code Reviews| Index: chrome/browser/printing/pdf_to_emf_converter.cc |
| diff --git a/chrome/browser/printing/pdf_to_emf_converter.cc b/chrome/browser/printing/pdf_to_emf_converter.cc |
| index fb0be329e76d0325e4b0c20645adf832fb1d3303..9aa80cf6aa54b02948c0df7459974e141e8a628d 100644 |
| --- a/chrome/browser/printing/pdf_to_emf_converter.cc |
| +++ b/chrome/browser/printing/pdf_to_emf_converter.cc |
| @@ -20,14 +20,15 @@ |
| #include "base/memory/ptr_util.h" |
| #include "base/threading/thread_task_runner_handle.h" |
| #include "chrome/common/chrome_utility_messages.h" |
| -#include "chrome/common/chrome_utility_printing_messages.h" |
| #include "chrome/grit/generated_resources.h" |
| +#include "components/printing/common/printing.mojom.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/child_process_data.h" |
| -#include "content/public/browser/utility_process_host.h" |
| -#include "content/public/browser/utility_process_host_client.h" |
| +#include "content/public/browser/utility_process_mojo_client.h" |
| +#include "mojo/public/cpp/bindings/binding.h" |
| #include "printing/emf_win.h" |
| #include "printing/pdf_render_settings.h" |
| +#include "services/service_manager/public/cpp/interface_provider.h" |
| #include "ui/base/l10n/l10n_util.h" |
| namespace printing { |
| @@ -89,11 +90,11 @@ class LazyEmf : public MetafilePlayer { |
| }; |
| // Converts PDF into EMF. |
| -// Class uses 3 threads: UI, IO and FILE. |
| +// Class uses 2 threads: UI and FILE. |
| // Internal workflow is following: |
| // 1. Create instance on the UI thread. (files_, settings_,) |
| // 2. Create pdf file on the FILE thread. |
| -// 3. Start utility process and start conversion on the IO thread. |
| +// 3. Start utility process and start conversion on the UI thread. |
| // 4. Utility process returns page count. |
| // 5. For each page: |
| // 1. Clients requests page with file handle to a temp file. |
| @@ -102,7 +103,8 @@ class LazyEmf : public MetafilePlayer { |
| // All these steps work sequentially, so no data should be accessed |
| // simultaneously by several threads. |
| class PdfToEmfUtilityProcessHostClient |
| - : public content::UtilityProcessHostClient { |
| + : public base::RefCountedThreadSafe<PdfToEmfUtilityProcessHostClient>, |
| + public mojom::FontPreCaching { |
| public: |
| PdfToEmfUtilityProcessHostClient( |
| base::WeakPtr<PdfToEmfConverterImpl> converter, |
| @@ -117,15 +119,6 @@ class PdfToEmfUtilityProcessHostClient |
| void Stop(); |
| - // Needs to be public to handle ChromeUtilityHostMsg_PreCacheFontCharacters |
| - // sync message replies. |
| - bool Send(IPC::Message* msg); |
| - |
| - // UtilityProcessHostClient implementation. |
| - void OnProcessCrashed(int exit_code) override; |
| - void OnProcessLaunchFailed(int exit_code) override; |
| - bool OnMessageReceived(const IPC::Message& message) override; |
| - |
| private: |
| class GetPageCallbackData { |
| public: |
| @@ -159,13 +152,18 @@ class PdfToEmfUtilityProcessHostClient |
| DISALLOW_COPY_AND_ASSIGN(GetPageCallbackData); |
| }; |
| + friend class base::RefCountedThreadSafe<PdfToEmfUtilityProcessHostClient>; |
| ~PdfToEmfUtilityProcessHostClient() override; |
| // Message handlers. |
| void OnPageCount(int page_count); |
| void OnPageDone(bool success, float scale_factor); |
| - void OnPreCacheFontCharacters(const LOGFONT& log_font, |
| - const base::string16& characters); |
| + |
| + // mojom::FontPreCaching: |
| + void PreCacheFontCharacters( |
| + const LOGFONT& log_font, |
| + const base::string16& characters, |
| + const PreCacheFontCharactersCallback& callback) override; |
| void OnFailed(); |
| void OnTempPdfReady(bool print_text_with_gdi, ScopedTempFile pdf); |
| @@ -180,8 +178,8 @@ class PdfToEmfUtilityProcessHostClient |
| // Document loaded callback. |
| PdfToEmfConverter::StartCallback start_callback_; |
| - // Process host for IPC. |
| - base::WeakPtr<content::UtilityProcessHost> utility_process_host_; |
| + std::unique_ptr<content::UtilityProcessMojoClient<mojom::PrintingFactory>> |
| + utility_client_; |
| // Queue of callbacks for GetPage() requests. Utility process should reply |
| // with PageDone in the same order as requests were received. |
| @@ -189,6 +187,12 @@ class PdfToEmfUtilityProcessHostClient |
| typedef std::queue<GetPageCallbackData> GetPageCallbacks; |
| GetPageCallbacks get_page_callbacks_; |
| + // Bound and used on the UI thread. |
| + mojom::PrintingPtr printing_; |
| + |
| + // Interface that receives font precaching requests. |
| + mojo::Binding<mojom::FontPreCaching> binding_; |
| + |
| DISALLOW_COPY_AND_ASSIGN(PdfToEmfUtilityProcessHostClient); |
| }; |
| @@ -297,8 +301,7 @@ bool LazyEmf::LoadEmf(Emf* emf) const { |
| PdfToEmfUtilityProcessHostClient::PdfToEmfUtilityProcessHostClient( |
| base::WeakPtr<PdfToEmfConverterImpl> converter, |
| const PdfRenderSettings& settings) |
| - : converter_(converter), settings_(settings) { |
| -} |
| + : converter_(converter), settings_(settings), binding_(this) {} |
| PdfToEmfUtilityProcessHostClient::~PdfToEmfUtilityProcessHostClient() { |
| } |
| @@ -307,13 +310,7 @@ void PdfToEmfUtilityProcessHostClient::Start( |
| const scoped_refptr<base::RefCountedMemory>& data, |
| bool print_text_with_gdi, |
| const PdfToEmfConverter::StartCallback& start_callback) { |
| - if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| - BrowserThread::PostTask( |
| - BrowserThread::IO, FROM_HERE, |
| - base::Bind(&PdfToEmfUtilityProcessHostClient::Start, this, data, |
| - print_text_with_gdi, start_callback)); |
| - return; |
| - } |
| + DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| // Store callback before any OnFailed() call to make it called on failure. |
| start_callback_ = start_callback; |
| @@ -321,11 +318,14 @@ void PdfToEmfUtilityProcessHostClient::Start( |
| // NOTE: This process _must_ be sandboxed, otherwise the pdf dll will load |
| // gdiplus.dll, change how rendering happens, and not be able to correctly |
| // generate when sent to a metafile DC. |
| - utility_process_host_ = content::UtilityProcessHost::Create( |
| - this, base::ThreadTaskRunnerHandle::Get()) |
| - ->AsWeakPtr(); |
| - utility_process_host_->SetName(l10n_util::GetStringUTF16( |
| - IDS_UTILITY_PROCESS_EMF_CONVERTOR_NAME)); |
| + utility_client_.reset( |
|
Sam McNally
2017/01/05 06:23:15
Prefer base::MakeUnique over std::unique_ptr::rese
tibell
2017/01/12 03:30:14
Done.
|
| + new content::UtilityProcessMojoClient<mojom::PrintingFactory>( |
| + l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_EMF_CONVERTOR_NAME))); |
| + utility_client_->set_error_callback( |
| + base::Bind(&PdfToEmfUtilityProcessHostClient::OnFailed, this)); |
| + utility_client_->Start(); |
| + utility_client_->service()->MakePrinting( |
| + mojo::MakeRequest(&printing_), binding_.CreateInterfacePtrAndBind()); |
| BrowserThread::PostTaskAndReplyWithResult( |
| BrowserThread::FILE, FROM_HERE, |
| @@ -336,45 +336,31 @@ void PdfToEmfUtilityProcessHostClient::Start( |
| void PdfToEmfUtilityProcessHostClient::OnTempPdfReady(bool print_text_with_gdi, |
| ScopedTempFile pdf) { |
| - DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - if (!utility_process_host_ || !pdf) |
| + DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| + if (!utility_client_ || !pdf) |
| return OnFailed(); |
| - // Should reply with OnPageCount(). |
| - Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles( |
| - IPC::GetPlatformFileForTransit(pdf->GetPlatformFile(), false), settings_, |
| - print_text_with_gdi)); |
| + printing_->RenderPDFPagesToMetafiles( |
| + pdf->Duplicate(), settings_, print_text_with_gdi, |
| + base::Bind(&PdfToEmfUtilityProcessHostClient::OnPageCount, this)); |
| } |
| void PdfToEmfUtilityProcessHostClient::OnPageCount(int page_count) { |
| - DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| if (start_callback_.is_null()) |
| return OnFailed(); |
| - BrowserThread::PostTask(BrowserThread::UI, |
| - FROM_HERE, |
| - base::Bind(&PdfToEmfConverterImpl::RunCallback, |
| - converter_, |
| - base::Bind(start_callback_, page_count))); |
| + start_callback_.Run(page_count); |
|
Sam McNally
2017/01/05 06:23:15
base::ResetAndReturn(&start_callback_).Run(page_co
tibell
2017/01/12 03:30:14
Done.
|
| start_callback_.Reset(); |
| } |
| void PdfToEmfUtilityProcessHostClient::GetPage( |
| int page_number, |
| const PdfToEmfConverter::GetPageCallback& get_page_callback) { |
| - if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| - BrowserThread::PostTask( |
| - BrowserThread::IO, |
| - FROM_HERE, |
| - base::Bind(&PdfToEmfUtilityProcessHostClient::GetPage, |
| - this, |
| - page_number, |
| - get_page_callback)); |
| - return; |
| - } |
| + DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| // Store callback before any OnFailed() call to make it called on failure. |
| get_page_callbacks_.push(GetPageCallbackData(page_number, get_page_callback)); |
| - if (!utility_process_host_) |
| + if (!utility_client_) |
| return OnFailed(); |
| BrowserThread::PostTaskAndReplyWithResult( |
| @@ -389,20 +375,18 @@ void PdfToEmfUtilityProcessHostClient::GetPage( |
| void PdfToEmfUtilityProcessHostClient::OnTempEmfReady( |
| GetPageCallbackData* callback_data, |
| ScopedTempFile emf) { |
| - DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - if (!utility_process_host_ || !emf) |
| + DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| + if (!utility_client_ || !emf) |
| return OnFailed(); |
| - IPC::PlatformFileForTransit transit = |
| - IPC::GetPlatformFileForTransit(emf->GetPlatformFile(), false); |
| callback_data->set_emf(std::move(emf)); |
| - // Should reply with OnPageDone(). |
| - Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage( |
| - callback_data->page_number(), transit)); |
| + printing_->RenderPDFPagesToMetafilesGetPage( |
| + callback_data->page_number(), emf->Duplicate(), |
| + base::Bind(&PdfToEmfUtilityProcessHostClient::OnPageDone, this)); |
| } |
| void PdfToEmfUtilityProcessHostClient::OnPageDone(bool success, |
| float scale_factor) { |
| - DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| if (get_page_callbacks_.empty()) |
| return OnFailed(); |
| GetPageCallbackData& data = get_page_callbacks_.front(); |
| @@ -415,20 +399,14 @@ void PdfToEmfUtilityProcessHostClient::OnPageDone(bool success, |
| emf = base::MakeUnique<LazyEmf>(temp_dir_, std::move(temp_emf)); |
| } |
| - BrowserThread::PostTask(BrowserThread::UI, |
| - FROM_HERE, |
| - base::Bind(&PdfToEmfConverterImpl::RunCallback, |
| - converter_, |
| - base::Bind(data.callback(), |
| - data.page_number(), |
| - scale_factor, |
| - base::Passed(&emf)))); |
| + data.callback().Run(data.page_number(), scale_factor, std::move(emf)); |
| get_page_callbacks_.pop(); |
| } |
| -void PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters( |
| +void PdfToEmfUtilityProcessHostClient::PreCacheFontCharacters( |
|
Sam McNally
2017/01/05 06:23:15
Is the UI thread the right place to be doing this?
tibell
2017/01/12 03:30:14
Done.
|
| const LOGFONT& font, |
| - const base::string16& str) { |
| + const base::string16& str, |
| + const PreCacheFontCharactersCallback& callback) { |
| // TODO(scottmg): pdf/ppapi still require the renderer to be able to precache |
| // GDI fonts (http://crbug.com/383227), even when using DirectWrite. |
| // Eventually this shouldn't be added and should be moved to |
| @@ -456,56 +434,21 @@ void PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters( |
| if (metafile) |
| DeleteEnhMetaFile(metafile); |
| + callback.Run(); |
| } |
| void PdfToEmfUtilityProcessHostClient::Stop() { |
| - if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| - BrowserThread::PostTask( |
| - BrowserThread::IO, |
| - FROM_HERE, |
| - base::Bind(&PdfToEmfUtilityProcessHostClient::Stop, this)); |
| - return; |
| - } |
| - Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop()); |
| -} |
| - |
| -void PdfToEmfUtilityProcessHostClient::OnProcessCrashed(int exit_code) { |
| - OnFailed(); |
| -} |
| - |
| -void PdfToEmfUtilityProcessHostClient::OnProcessLaunchFailed(int exit_code) { |
| - OnFailed(); |
| -} |
| - |
| -bool PdfToEmfUtilityProcessHostClient::OnMessageReceived( |
| - const IPC::Message& message) { |
| - bool handled = true; |
| - IPC_BEGIN_MESSAGE_MAP(PdfToEmfUtilityProcessHostClient, message) |
| - IPC_MESSAGE_HANDLER( |
| - ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount, OnPageCount) |
| - IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone, |
| - OnPageDone) |
| - IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_PreCacheFontCharacters, |
| - OnPreCacheFontCharacters) |
| - IPC_MESSAGE_UNHANDLED(handled = false) |
| - IPC_END_MESSAGE_MAP() |
| - return handled; |
| -} |
| - |
| -bool PdfToEmfUtilityProcessHostClient::Send(IPC::Message* msg) { |
| - if (utility_process_host_) |
| - return utility_process_host_->Send(msg); |
| - delete msg; |
| - return false; |
| + DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| + printing_.reset(); |
| } |
| void PdfToEmfUtilityProcessHostClient::OnFailed() { |
| - DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| if (!start_callback_.is_null()) |
| OnPageCount(0); |
| while (!get_page_callbacks_.empty()) |
| OnPageDone(false, 0.0f); |
| - utility_process_host_.reset(); |
| + utility_client_.reset(); |
| } |
| PdfToEmfConverterImpl::PdfToEmfConverterImpl() : weak_ptr_factory_(this) { |