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
3 // found in the LICENSE file.
5 #include "chrome/browser/printing/print_preview_message_handler.h"
8 #include "base/memory/shared_memory.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/printing/print_job_manager.h"
11 #include "chrome/browser/printing/printer_query.h"
12 #include "chrome/common/print_messages.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/browser/render_frame_host.h"
15 #include "content/public/browser/render_view_host.h"
16 #include "content/public/browser/web_contents.h"
17 #include "printing/page_size_margins.h"
18 #include "printing/print_job_constants.h"
19 #include "printing/pdf_metafile_skia.h"
20 #include "tizen/common/env_variables.h"
22 #include "atom/common/node_includes.h"
24 using content::BrowserThread;
25 using content::WebContents;
27 DEFINE_WEB_CONTENTS_USER_DATA_KEY(printing::PrintPreviewMessageHandler);
31 void StopWorker(int document_cookie) {
32 if (document_cookie <= 0)
34 scoped_refptr<printing::PrintQueriesQueue> queue =
35 g_browser_process->print_job_manager()->queue();
36 scoped_refptr<printing::PrinterQuery> printer_query =
37 queue->PopPrinterQuery(document_cookie);
38 if (printer_query.get()) {
39 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
40 base::Bind(&printing::PrinterQuery::StopWorker,
45 char* CopyPDFDataOnIOThread(
46 const PrintHostMsg_DidPreviewDocument_Params& params) {
47 DCHECK_CURRENTLY_ON(BrowserThread::IO);
48 std::unique_ptr<base::SharedMemory> shared_buf(
49 new base::SharedMemory(params.metafile_data_handle, true));
50 if (!shared_buf->Map(params.data_size))
52 char* pdf_data = new char[params.data_size];
53 memcpy(pdf_data, shared_buf->memory(), params.data_size);
57 void FreeNodeBufferData(char* data, void* hint) {
66 PrintPreviewMessageHandler::PrintPreviewMessageHandler(
67 WebContents* web_contents)
68 : content::WebContentsObserver(web_contents) {
72 PrintPreviewMessageHandler::~PrintPreviewMessageHandler() {
75 void PrintPreviewMessageHandler::OnMetafileReadyForPrinting(
76 const PrintHostMsg_DidPreviewDocument_Params& params) {
77 // Always try to stop the worker.
78 StopWorker(params.document_cookie);
80 if (params.expected_pages_count <= 0) {
85 BrowserThread::PostTaskAndReplyWithResult(
88 base::Bind(&CopyPDFDataOnIOThread, params),
89 base::Bind(&PrintPreviewMessageHandler::RunPrintToPDFCallback,
90 base::Unretained(this),
91 params.preview_request_id,
95 void PrintPreviewMessageHandler::OnPrintPreviewFailed(int document_cookie,
97 StopWorker(document_cookie);
98 RunPrintToPDFCallback(request_id, 0, nullptr);
101 bool PrintPreviewMessageHandler::OnMessageReceived(
102 const IPC::Message& message,
103 content::RenderFrameHost* render_frame_host) {
105 IPC_BEGIN_MESSAGE_MAP(PrintPreviewMessageHandler, message)
106 IPC_MESSAGE_HANDLER(PrintHostMsg_MetafileReadyForPrinting,
107 OnMetafileReadyForPrinting)
108 IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewFailed,
109 OnPrintPreviewFailed)
110 IPC_MESSAGE_UNHANDLED(handled = false)
111 IPC_END_MESSAGE_MAP()
115 void PrintPreviewMessageHandler::PrintToPDF(
116 const base::DictionaryValue& options,
117 const atom::api::WebContents::PrintToPDFCallback& callback) {
119 options.GetInteger(printing::kPreviewRequestID, &request_id);
120 print_to_pdf_callback_map_[request_id] = callback;
122 content::RenderFrameHost* rfh = web_contents()->GetMainFrame();
123 rfh->Send(new PrintMsg_PrintPreview(rfh->GetRoutingID(), options));
126 void PrintPreviewMessageHandler::RunPrintToPDFCallback(
127 int request_id, uint32_t data_size, char* data) {
128 DCHECK_CURRENTLY_ON(BrowserThread::UI);
130 v8::Isolate* isolate = v8::Isolate::GetCurrent();
131 if (!::tizen::is_single_process)
132 v8::Locker locker(isolate);
133 v8::HandleScope handle_scope(isolate);
135 v8::Local<v8::Value> buffer = node::Buffer::New(isolate,
136 data, static_cast<size_t>(data_size), &FreeNodeBufferData, nullptr)
138 print_to_pdf_callback_map_[request_id].Run(v8::Null(isolate), buffer);
140 v8::Local<v8::String> error_message = v8::String::NewFromUtf8(isolate,
141 "Failed to generate PDF");
142 print_to_pdf_callback_map_[request_id].Run(
143 v8::Exception::Error(error_message), v8::Null(isolate));
145 print_to_pdf_callback_map_.erase(request_id);
148 } // namespace printing