Run Tizen Webapps in single process mode
[platform/framework/web/crosswalk-tizen.git] / chromium_src / chrome / browser / printing / print_preview_message_handler.cc
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.
4
5 #include "chrome/browser/printing/print_preview_message_handler.h"
6
7 #include "base/bind.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"
21
22 #include "atom/common/node_includes.h"
23
24 using content::BrowserThread;
25 using content::WebContents;
26
27 DEFINE_WEB_CONTENTS_USER_DATA_KEY(printing::PrintPreviewMessageHandler);
28
29 namespace {
30
31 void StopWorker(int document_cookie) {
32   if (document_cookie <= 0)
33     return;
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,
41                                        printer_query));
42   }
43 }
44
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))
51     return nullptr;
52   char* pdf_data = new char[params.data_size];
53   memcpy(pdf_data, shared_buf->memory(), params.data_size);
54   return pdf_data;
55 }
56
57 void FreeNodeBufferData(char* data, void* hint) {
58   delete[] data;
59 }
60
61 }  // namespace
62
63 namespace printing {
64
65
66 PrintPreviewMessageHandler::PrintPreviewMessageHandler(
67     WebContents* web_contents)
68     : content::WebContentsObserver(web_contents) {
69   DCHECK(web_contents);
70 }
71
72 PrintPreviewMessageHandler::~PrintPreviewMessageHandler() {
73 }
74
75 void PrintPreviewMessageHandler::OnMetafileReadyForPrinting(
76     const PrintHostMsg_DidPreviewDocument_Params& params) {
77   // Always try to stop the worker.
78   StopWorker(params.document_cookie);
79
80   if (params.expected_pages_count <= 0) {
81     NOTREACHED();
82     return;
83   }
84
85   BrowserThread::PostTaskAndReplyWithResult(
86       BrowserThread::IO,
87       FROM_HERE,
88       base::Bind(&CopyPDFDataOnIOThread, params),
89       base::Bind(&PrintPreviewMessageHandler::RunPrintToPDFCallback,
90                  base::Unretained(this),
91                  params.preview_request_id,
92                  params.data_size));
93 }
94
95 void PrintPreviewMessageHandler::OnPrintPreviewFailed(int document_cookie,
96                                                       int request_id) {
97   StopWorker(document_cookie);
98   RunPrintToPDFCallback(request_id, 0, nullptr);
99 }
100
101 bool PrintPreviewMessageHandler::OnMessageReceived(
102     const IPC::Message& message,
103     content::RenderFrameHost* render_frame_host) {
104   bool handled = true;
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()
112   return handled;
113 }
114
115 void PrintPreviewMessageHandler::PrintToPDF(
116     const base::DictionaryValue& options,
117     const atom::api::WebContents::PrintToPDFCallback& callback) {
118   int request_id;
119   options.GetInteger(printing::kPreviewRequestID, &request_id);
120   print_to_pdf_callback_map_[request_id] = callback;
121
122   content::RenderFrameHost* rfh = web_contents()->GetMainFrame();
123   rfh->Send(new PrintMsg_PrintPreview(rfh->GetRoutingID(), options));
124 }
125
126 void PrintPreviewMessageHandler::RunPrintToPDFCallback(
127     int request_id, uint32_t data_size, char* data) {
128   DCHECK_CURRENTLY_ON(BrowserThread::UI);
129
130   v8::Isolate* isolate = v8::Isolate::GetCurrent();
131   if (!::tizen::is_single_process)
132     v8::Locker locker(isolate);
133   v8::HandleScope handle_scope(isolate);
134   if (data) {
135     v8::Local<v8::Value> buffer = node::Buffer::New(isolate,
136         data, static_cast<size_t>(data_size), &FreeNodeBufferData, nullptr)
137         .ToLocalChecked();
138     print_to_pdf_callback_map_[request_id].Run(v8::Null(isolate), buffer);
139   } else {
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));
144   }
145   print_to_pdf_callback_map_.erase(request_id);
146 }
147
148 }  // namespace printing