diff options
Diffstat (limited to 'src/core/printing/print_view_manager_base_qt.cpp')
-rw-r--r-- | src/core/printing/print_view_manager_base_qt.cpp | 180 |
1 files changed, 121 insertions, 59 deletions
diff --git a/src/core/printing/print_view_manager_base_qt.cpp b/src/core/printing/print_view_manager_base_qt.cpp index 0f7ec1c70..ad35209f1 100644 --- a/src/core/printing/print_view_manager_base_qt.cpp +++ b/src/core/printing/print_view_manager_base_qt.cpp @@ -58,10 +58,13 @@ #include "chrome/browser/printing/print_job.h" #include "chrome/browser/printing/print_job_manager.h" #include "chrome/browser/printing/printer_query.h" +#include "components/printing/browser/print_manager_utils.h" +#include "components/printing/common/print.mojom.h" #include "components/printing/common/print_messages.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" @@ -71,12 +74,71 @@ namespace QtWebEngineCore { +namespace { + +// Runs |callback| with |params| to reply to +// mojom::PrintManagerHost::GetDefaultPrintSettings. +void GetDefaultPrintSettingsReply(printing::mojom::PrintManagerHost::GetDefaultPrintSettingsCallback callback, + printing::mojom::PrintParamsPtr params) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + std::move(callback).Run(std::move(params)); +} + +void GetDefaultPrintSettingsReplyOnIO(scoped_refptr<printing::PrintQueriesQueue> queue, + std::unique_ptr<printing::PrinterQuery> printer_query, + printing::mojom::PrintManagerHost::GetDefaultPrintSettingsCallback callback) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + printing::mojom::PrintParamsPtr params = printing::mojom::PrintParams::New(); + if (printer_query && printer_query->last_status() == printing::PrintingContext::OK) { + RenderParamsFromPrintSettings(printer_query->settings(), params.get()); + params->document_cookie = printer_query->cookie(); + } + + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, + base::BindOnce(&GetDefaultPrintSettingsReply, + std::move(callback), std::move(params))); + + // If printing was enabled. + if (printer_query) { + // If user hasn't cancelled. + if (printer_query->cookie() && printer_query->settings().dpi()) { + queue->QueuePrinterQuery(std::move(printer_query)); + } else { + printer_query->StopWorker(); + } + } +} + +void GetDefaultPrintSettingsOnIO(printing::mojom::PrintManagerHost::GetDefaultPrintSettingsCallback callback, + scoped_refptr<printing::PrintQueriesQueue> queue, + int process_id, int routing_id) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + + std::unique_ptr<printing::PrinterQuery> printer_query = queue->PopPrinterQuery(0); + if (!printer_query) + printer_query = queue->CreatePrinterQuery(process_id, routing_id); + + // Loads default settings. This is asynchronous, only the mojo message sender + // will hang until the settings are retrieved. + auto *printer_query_ptr = printer_query.get(); + printer_query_ptr->GetSettings( + printing::PrinterQuery::GetSettingsAskParam::DEFAULTS, 0, false, + printing::mojom::MarginType::kDefaultMargins, false, false, + base::BindOnce(&GetDefaultPrintSettingsReplyOnIO, queue, + std::move(printer_query), std::move(callback))); +} + +} // namespace + PrintViewManagerBaseQt::PrintViewManagerBaseQt(content::WebContents *contents) : printing::PrintManager(contents) - , m_isInsideInnerMessageLoop(false) + , m_printingRFH(nullptr) , m_didPrintingSucceed(false) , m_printerQueriesQueue(WebEngineContext::current()->getPrintJobManager()->queue()) - , m_printingRFH(nullptr) { // FIXME: Check if this needs to be executed async: // TODO: Add isEnabled to profile @@ -118,8 +180,7 @@ base::string16 PrintViewManagerBaseQt::RenderSourceName() return toString16(QLatin1String("")); } -void PrintViewManagerBaseQt::PrintDocument(printing::PrintedDocument *document, - const scoped_refptr<base::RefCountedMemory> &print_data, +void PrintViewManagerBaseQt::PrintDocument(scoped_refptr<base::RefCountedMemory> print_data, const gfx::Size &page_size, const gfx::Rect &content_area, const gfx::Point &offsets) @@ -129,22 +190,26 @@ void PrintViewManagerBaseQt::PrintDocument(printing::PrintedDocument *document, CHECK(metafile->InitFromData(*print_data)); // Update the rendered document. It will send notifications to the listener. + printing::PrintedDocument* document = m_printJob->document(); document->SetDocument(std::move(metafile)); ShouldQuitFromInnerMessageLoop(); } -printing::PrintedDocument *PrintViewManagerBaseQt::GetDocument(int cookie) +void PrintViewManagerBaseQt::DidGetPrintedPagesCount(int32_t cookie, uint32_t number_pages) +{ + PrintManager::DidGetPrintedPagesCount(cookie, number_pages); + OpportunisticallyCreatePrintJob(cookie); +} + +bool PrintViewManagerBaseQt::PrintJobHasDocument(int cookie) { if (!OpportunisticallyCreatePrintJob(cookie)) - return nullptr; + return false; + // These checks may fail since we are completely asynchronous. Old spurious + // messages can be received if one of the processes is overloaded. printing::PrintedDocument* document = m_printJob->document(); - if (!document || cookie != document->cookie()) { - // Out of sync. It may happen since we are completely asynchronous. Old - // spurious messages can be received if one of the processes is overloaded. - return nullptr; - } - return document; + return document && document->cookie() == cookie; } // IPC handlers @@ -152,44 +217,61 @@ void PrintViewManagerBaseQt::OnDidPrintDocument(content::RenderFrameHost* /*rend const printing::mojom::DidPrintDocumentParams ¶ms, std::unique_ptr<DelayedFrameDispatchHelper> helper) { - printing::PrintedDocument *document = GetDocument(params.document_cookie); - if (!document) + if (!PrintJobHasDocument(params.document_cookie)) return; - const auto &content = params.content; - if (!content->metafile_data_region.IsValid()) { + const printing::mojom::DidPrintContentParams &content = *params.content; + if (!content.metafile_data_region.IsValid()) { NOTREACHED() << "invalid memory handle"; web_contents()->Stop(); return; } - auto data = base::RefCountedSharedMemoryMapping::CreateFromWholeRegion(content->metafile_data_region); + auto data = base::RefCountedSharedMemoryMapping::CreateFromWholeRegion(content.metafile_data_region); if (!data) { NOTREACHED() << "couldn't map"; web_contents()->Stop(); return; } - PrintDocument(document, data, params.page_size, params.content_area, + PrintDocument(data, params.page_size, params.content_area, params.physical_offsets); if (helper) helper->SendCompleted(); } -void PrintViewManagerBaseQt::OnGetDefaultPrintSettings(content::RenderFrameHost *render_frame_host, - IPC::Message *reply_msg) +void PrintViewManagerBaseQt::GetDefaultPrintSettings(GetDefaultPrintSettingsCallback callback) { - NOTREACHED() << "should be handled by printing::PrintingMessageFilter"; + content::RenderFrameHost* render_frame_host = + print_manager_host_receivers_.GetCurrentTargetFrame(); + + content::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, + base::BindOnce(&GetDefaultPrintSettingsOnIO, std::move(callback), m_printerQueriesQueue, + render_frame_host->GetProcess()->GetID(), + render_frame_host->GetRoutingID())); +} + +void PrintViewManagerBaseQt::PrintingFailed(int32_t cookie) +{ + PrintManager::PrintingFailed(cookie); + + ReleasePrinterQuery(); + + content::NotificationService::current()->Notify( + chrome::NOTIFICATION_PRINT_JOB_RELEASED, + content::Source<content::WebContents>(web_contents()), + content::NotificationService::NoDetails()); } void PrintViewManagerBaseQt::OnScriptedPrint(content::RenderFrameHost *render_frame_host, - const PrintHostMsg_ScriptedPrint_Params ¶ms, + const printing::mojom::ScriptedPrintParams ¶ms, IPC::Message *reply_msg) { NOTREACHED() << "should be handled by printing::PrintingMessageFilter"; } -void PrintViewManagerBaseQt::OnShowInvalidPrinterSettingsError() +void PrintViewManagerBaseQt::ShowInvalidPrinterSettingsError() { } @@ -202,6 +284,8 @@ void PrintViewManagerBaseQt::DidStartLoading() // so m_printingRFH is never set and used at the moment. void PrintViewManagerBaseQt::RenderFrameDeleted(content::RenderFrameHost *render_frame_host) { + PrintManager::RenderFrameDeleted(render_frame_host); + // Terminates or cancels the print job if one was pending. if (render_frame_host != m_printingRFH) return; @@ -215,7 +299,7 @@ void PrintViewManagerBaseQt::RenderFrameDeleted(content::RenderFrameHost *render return; scoped_refptr<printing::PrintedDocument> document(m_printJob->document()); - if (document.get()) { + if (document) { // If IsComplete() returns false, the document isn't completely rendered. // Since our renderer is gone, there's nothing to do, cancel it. Otherwise, // the print job may finish without problem. @@ -223,18 +307,6 @@ void PrintViewManagerBaseQt::RenderFrameDeleted(content::RenderFrameHost *render } } -bool PrintViewManagerBaseQt::OnMessageReceived(const IPC::Message& message, - content::RenderFrameHost* render_frame_host) -{ - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(PrintViewManagerBaseQt, message) - IPC_MESSAGE_HANDLER(PrintHostMsg_ShowInvalidPrinterSettingsError, - OnShowInvalidPrinterSettingsError); - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled || PrintManager::OnMessageReceived(message, render_frame_host); -} - void PrintViewManagerBaseQt::Observe(int type, const content::NotificationSource& /*source*/, const content::NotificationDetails& details) @@ -332,28 +404,21 @@ bool PrintViewManagerBaseQt::RenderAllMissingPagesNow() return true; } -// Quits the current message loop if these conditions hold true: a document is -// loaded and is complete and waiting_for_pages_to_be_rendered_ is true. This -// function is called in DidPrintPage() or on ALL_PAGES_REQUESTED -// notification. The inner message loop is created was created by -// RenderAllMissingPagesNow(). void PrintViewManagerBaseQt::ShouldQuitFromInnerMessageLoop() { // Look at the reason. DCHECK(m_printJob->document()); - if (m_printJob->document() && - m_printJob->document()->IsComplete() && - m_isInsideInnerMessageLoop) { - // We are in a message loop created by RenderAllMissingPagesNow. Quit from - // it. - base::RunLoop::QuitCurrentWhenIdleDeprecated(); - m_isInsideInnerMessageLoop = false; + if (m_printJob->document() && m_printJob->document()->IsComplete() && m_quitInnerLoop) { + // We are in a message loop created by RenderAllMissingPagesNow. Quit from + // it. + std::move(m_quitInnerLoop).Run(); } } bool PrintViewManagerBaseQt::CreateNewPrintJob(std::unique_ptr<printing::PrinterQuery> query) { - DCHECK(!m_isInsideInnerMessageLoop); + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK(!m_quitInnerLoop); DCHECK(query); // Disconnect the current |m_printJob|. @@ -404,9 +469,9 @@ void PrintViewManagerBaseQt::TerminatePrintJob(bool cancel) if (cancel) { // We don't need the metafile data anymore because the printing is canceled. m_printJob->Cancel(); - m_isInsideInnerMessageLoop = false; + m_quitInnerLoop.Reset(); } else { - DCHECK(!m_isInsideInnerMessageLoop); + DCHECK(!m_quitInnerLoop); DCHECK(!m_printJob->document() || m_printJob->document()->IsComplete()); // WebContents is either dying or navigating elsewhere. We need to render @@ -434,7 +499,8 @@ void PrintViewManagerBaseQt::ReleasePrintJob() m_printJob = nullptr; } -bool PrintViewManagerBaseQt::RunInnerMessageLoop() { +bool PrintViewManagerBaseQt::RunInnerMessageLoop() +{ // This value may actually be too low: // // - If we're looping because of printer settings initialization, the premise @@ -453,7 +519,7 @@ bool PrintViewManagerBaseQt::RunInnerMessageLoop() { base::TimeDelta::FromMilliseconds(kPrinterSettingsTimeout), run_loop.QuitWhenIdleClosure()); - m_isInsideInnerMessageLoop = true; + m_quitInnerLoop = run_loop.QuitClosure(); // Need to enable recursive task. { @@ -461,12 +527,8 @@ bool PrintViewManagerBaseQt::RunInnerMessageLoop() { run_loop.Run(); } - bool success = true; - if (m_isInsideInnerMessageLoop) { - // Ok we timed out. That's sad. - m_isInsideInnerMessageLoop = false; - success = false; - } + bool success = !m_quitInnerLoop; + m_quitInnerLoop.Reset(); return success; } |