summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-16 00:29:22 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-16 00:29:22 +0000
commitfbea02332ae95f590c8a84019b582fa35e788a7c (patch)
treeeeff857a083663f3d5556fcff304b5fd05e32eb2 /chrome
parent0018067c7afbdf516d1845b35a3a245d96910f66 (diff)
downloadchromium_src-fbea02332ae95f590c8a84019b582fa35e788a7c.zip
chromium_src-fbea02332ae95f590c8a84019b582fa35e788a7c.tar.gz
chromium_src-fbea02332ae95f590c8a84019b582fa35e788a7c.tar.bz2
Linux: print page to file rather than using shared memory to send it to the browser.
BUG=9847 adapted from patch by <minyu.huang [at] gmail> Review URL: http://codereview.chromium.org/203062 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26308 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.cc29
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.h10
-rw-r--r--chrome/browser/renderer_host/resource_message_filter_gtk.cc63
-rw-r--r--chrome/common/render_messages_internal.h10
-rw-r--r--chrome/common/temp_scaffolding_stubs.cc48
-rw-r--r--chrome/common/temp_scaffolding_stubs.h4
-rw-r--r--chrome/renderer/print_web_view_helper_linux.cc96
7 files changed, 121 insertions, 139 deletions
diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc
index 095131f..4a5de3a 100644
--- a/chrome/browser/renderer_host/resource_message_filter.cc
+++ b/chrome/browser/renderer_host/resource_message_filter.cc
@@ -339,8 +339,10 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(ViewHostMsg_DuplicateSection, OnDuplicateSection)
#endif
#if defined(OS_LINUX)
- IPC_MESSAGE_HANDLER(ViewHostMsg_AllocateShareMemory,
- OnAllocateShareMemory)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_AllocateTempFileForPrinting,
+ OnAllocateTempFileForPrinting)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_TempFileForPrintingWritten,
+ OnTempFileForPrintingWritten)
#endif
IPC_MESSAGE_HANDLER(ViewHostMsg_ResourceTypeStats, OnResourceTypeStats)
IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_ResolveProxy, OnResolveProxy)
@@ -706,29 +708,6 @@ void ResourceMessageFilter::OnDuplicateSection(
}
#endif
-#if defined(OS_LINUX)
-void ResourceMessageFilter::OnAllocateShareMemory(
- size_t buffer_size,
- base::SharedMemoryHandle* browser_handle) {
- // We don't want to allocate a super big chunk of memory.
- // 32MB should be large enough for printing on Linux.
- if (buffer_size > 32 * 1024 * 1024) {
- *browser_handle = base::SharedMemory::NULLHandle();
- NOTREACHED() << "Buffer too large: " << buffer_size;
- return;
- }
- base::SharedMemory shared_buf;
- shared_buf.Create(L"", false, false, buffer_size);
- if (shared_buf.Map(buffer_size)) {
- shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), browser_handle);
- } else {
- *browser_handle = base::SharedMemory::NULLHandle();
- NOTREACHED() << "Cannot map buffer";
- return;
- }
-}
-#endif
-
void ResourceMessageFilter::OnResourceTypeStats(
const WebCache::ResourceTypeStats& stats) {
HISTOGRAM_COUNTS("WebCoreCache.ImagesSizeKB",
diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h
index 897e373..dceaa3d 100644
--- a/chrome/browser/renderer_host/resource_message_filter.h
+++ b/chrome/browser/renderer_host/resource_message_filter.h
@@ -52,6 +52,9 @@ struct WebScreenInfo;
}
struct ViewHostMsg_ScriptedPrint_Params;
+#if defined(OS_LINUX)
+struct ViewHostMsg_DidPrintPage_Params;
+#endif
// This class filters out incoming IPC messages for network requests and
// processes them on the IPC thread. As a result, network requests are not
@@ -204,10 +207,11 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter,
#endif
#if defined(OS_LINUX)
- // Used to ask the browser allocate a block of shared memory for the renderer
+ // Used to ask the browser allocate a temporary file for the renderer
// to fill in resulting PDF in renderer.
- void OnAllocateShareMemory(size_t buffer_size,
- base::SharedMemoryHandle* browser_handle);
+ void OnAllocateTempFileForPrinting(base::FileDescriptor* temp_file_fd,
+ int* fd_in_browser);
+ void OnTempFileForPrintingWritten(int fd_in_browser);
#endif
void OnResourceTypeStats(const WebKit::WebCache::ResourceTypeStats& stats);
diff --git a/chrome/browser/renderer_host/resource_message_filter_gtk.cc b/chrome/browser/renderer_host/resource_message_filter_gtk.cc
index 1dd964d..8533cac 100644
--- a/chrome/browser/renderer_host/resource_message_filter_gtk.cc
+++ b/chrome/browser/renderer_host/resource_message_filter_gtk.cc
@@ -4,11 +4,20 @@
#include "chrome/browser/renderer_host/resource_message_filter.h"
+#include <fcntl.h>
+#include <map>
+
+#include "app/l10n_util.h"
#include "base/clipboard.h"
+#include "base/file_util.h"
#include "base/gfx/gtk_native_view_id_manager.h"
+#include "base/path_service.h"
+#include "base/singleton.h"
#include "chrome/browser/chrome_thread.h"
+#include "chrome/common/chrome_paths.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/x11_util.h"
+#include "grit/generated_resources.h"
#include "webkit/api/public/WebScreenInfo.h"
#include "webkit/api/public/x11/WebScreenInfoFactory.h"
@@ -16,6 +25,16 @@
using WebKit::WebScreenInfo;
using WebKit::WebScreenInfoFactory;
+namespace {
+
+typedef std::map<int, FilePath> FdMap;
+
+struct PrintingFileDescriptorMap {
+ FdMap map;
+};
+
+} // namespace
+
// We get null window_ids passed into the two functions below; please see
// http://crbug.com/9060 for more details.
@@ -210,3 +229,47 @@ void ResourceMessageFilter::OnClipboardReadHTML(Clipboard::Buffer buffer,
this, &ResourceMessageFilter::DoOnClipboardReadHTML, buffer,
reply_msg));
}
+
+// Called on the IO thread.
+void ResourceMessageFilter::OnAllocateTempFileForPrinting(
+ base::FileDescriptor* temp_file_fd, int* fd_in_browser) {
+ temp_file_fd->fd = *fd_in_browser = -1;
+
+ FilePath path;
+ if (!file_util::CreateTemporaryFile(&path))
+ return;
+
+ int fd = open(path.value().c_str(), O_WRONLY);
+ if (fd < 0)
+ return;
+
+ // We need to remember the FilePath of the temporary file because we need
+ // it when we want to rename/move it, and more importantly, to print it
+ // when we print by using gtk_print_job_set_source_file().
+ FdMap* map = &Singleton<PrintingFileDescriptorMap>::get()->map;
+ FdMap::iterator it = map->find(fd);
+ if (it != map->end()) {
+ NOTREACHED() << "The file descriptor is in use. fd=" << fd;
+ return;
+ }
+
+ (*map)[fd] = path;
+ temp_file_fd->fd = *fd_in_browser = fd;
+ temp_file_fd->auto_close = true;
+}
+
+// Called on the IO thread.
+void ResourceMessageFilter::OnTempFileForPrintingWritten(int fd_in_browser) {
+ FdMap* map = &Singleton<PrintingFileDescriptorMap>::get()->map;
+ FdMap::iterator it = map->find(fd_in_browser);
+ if (it == map->end()) {
+ NOTREACHED() << "Got a file descriptor that we didn't pass to the "
+ "renderer: " << fd_in_browser;
+ return;
+ }
+
+ // TODO(estade): print it.
+
+ // Erase the entry in the map.
+ map->erase(it);
+}
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 806c0e5..2916c17 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -1396,11 +1396,13 @@ IPC_BEGIN_MESSAGES(ViewHost)
#endif
#if defined(OS_LINUX)
- // Asks the browser create a block of shared memory for the renderer to fill
+ // Asks the browser create a temporary file for the renderer to fill
// in resulting NativeMetafile in printing.
- IPC_SYNC_MESSAGE_ROUTED1_1(ViewHostMsg_AllocateShareMemory,
- size_t /* buffer size */,
- base::SharedMemoryHandle /* browser handle */)
+ IPC_SYNC_MESSAGE_CONTROL0_2(ViewHostMsg_AllocateTempFileForPrinting,
+ base::FileDescriptor /* temp file fd */,
+ int /* fd in browser*/)
+ IPC_MESSAGE_CONTROL1(ViewHostMsg_TempFileForPrintingWritten,
+ int /* fd in browser */)
#endif
// Provide the browser process with information about the WebCore resource
diff --git a/chrome/common/temp_scaffolding_stubs.cc b/chrome/common/temp_scaffolding_stubs.cc
index 9b1ed6d..76d2d60 100644
--- a/chrome/common/temp_scaffolding_stubs.cc
+++ b/chrome/common/temp_scaffolding_stubs.cc
@@ -13,12 +13,8 @@
#include "chrome/browser/rlz/rlz.h"
#if defined(OS_LINUX)
-#include "base/path_service.h"
#include "chrome/browser/dock_info.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/common/chrome_paths.h"
#include "chrome/common/render_messages.h"
-#include "printing/native_metafile.h"
#endif
#if defined(OS_MACOSX)
@@ -326,47 +322,3 @@ void BookmarkManager::Show(Profile* profile) {
#endif
-//------------------------------------------------------------------------------
-
-#if defined(OS_LINUX)
-// TODO(myhuang): This is a quick hack for testing purpose. We should implement
-// PrintViewManager and other related classes later on Linux.
-namespace printing {
-
-void PrintViewManager::DidPrintPage(
- const ViewHostMsg_DidPrintPage_Params& params) {
- base::SharedMemory shared_buf(params.metafile_data_handle, true);
- if (!shared_buf.Map(params.data_size)) {
- NOTREACHED() << "couldn't map";
- owner_.Stop();
- return;
- }
-
- // The only format we can use now is PDF since Cairo needs to create a
- // temporary file for a PostScript surface. We do not allow disk I/O in the
- // renderer.
- scoped_ptr<NativeMetafile> metafile(
- new NativeMetafile(printing::NativeMetafile::PDF));
-
- if (!metafile->Init(shared_buf.memory(), params.data_size)) {
- NOTREACHED() << "Invalid metafile header";
- shared_buf.Unmap();
- owner_.Stop();
- return;
- }
-
- // Save the PDF file to default download location.
- // NOTE: Existing file will be overwritten.
- FilePath default_save_path;
- if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &default_save_path)) {
- NOTREACHED();
- }
- FilePath save_filename =
- default_save_path.Append(FilePath("chromium_printing_test.pdf"));
- metafile->SaveTo(save_filename);
- shared_buf.Unmap();
-}
-
-} // namespace printing
-
-#endif
diff --git a/chrome/common/temp_scaffolding_stubs.h b/chrome/common/temp_scaffolding_stubs.h
index 7b01f31..6f186ff 100644
--- a/chrome/common/temp_scaffolding_stubs.h
+++ b/chrome/common/temp_scaffolding_stubs.h
@@ -67,13 +67,9 @@ class PrintViewManager : public RenderViewHostDelegate::Printing {
NOTIMPLEMENTED();
}
-#if defined(OS_LINUX)
- virtual void DidPrintPage(const ViewHostMsg_DidPrintPage_Params& params);
-#else
virtual void DidPrintPage(const ViewHostMsg_DidPrintPage_Params& params) {
NOTIMPLEMENTED();
}
-#endif
private:
TabContents& owner_;
diff --git a/chrome/renderer/print_web_view_helper_linux.cc b/chrome/renderer/print_web_view_helper_linux.cc
index 211eb6f..b8e0ca2 100644
--- a/chrome/renderer/print_web_view_helper_linux.cc
+++ b/chrome/renderer/print_web_view_helper_linux.cc
@@ -4,6 +4,7 @@
#include "chrome/renderer/print_web_view_helper.h"
+#include "base/file_descriptor_posix.h"
#include "base/logging.h"
#include "chrome/common/render_messages.h"
#include "printing/native_metafile.h"
@@ -53,64 +54,49 @@ void PrintWebViewHelper::PrintPages(const ViewMsg_PrintPages_Params& params,
// TODO(myhuang): Send ViewHostMsg_DidGetPrintedPagesCount.
- if (page_count) {
- // We only can use PDF in the renderer because Cairo needs to create a
- // temporary file for a PostScript surface.
- printing::NativeMetafile metafile(printing::NativeMetafile::PDF);
- metafile.Init();
-
- ViewMsg_PrintPage_Params print_page_params;
- print_page_params.params = params.params;
- const gfx::Size& canvas_size = prep_frame_view.GetPrintCanvasSize();
- if (params.pages.empty()) {
- for (int i = 0; i < page_count; ++i) {
- print_page_params.page_number = i;
- PrintPage(print_page_params, canvas_size, frame, &metafile);
- }
- } else {
- for (size_t i = 0; i < params.pages.size(); ++i) {
- print_page_params.page_number = params.pages[i];
- PrintPage(print_page_params, canvas_size, frame, &metafile);
- }
- }
+ if (page_count == 0)
+ return;
- metafile.Close();
-
- // Get the size of the resulting metafile.
- unsigned int buf_size = metafile.GetDataSize();
- DCHECK_GT(buf_size, 0u);
-
- ViewHostMsg_DidPrintPage_Params did_page_params;
-
- // Ask the browser create the shared memory for us.
- if (Send(new ViewHostMsg_AllocateShareMemory(
- routing_id(),
- buf_size,
- &did_page_params.metafile_data_handle))) {
- if (did_page_params.metafile_data_handle.fd > -1) {
- base::SharedMemory shared_buf(did_page_params.metafile_data_handle,
- false);
- if (shared_buf.Map(buf_size)) {
- if (metafile.GetData(shared_buf.memory(), buf_size)) {
- // FIXME(myhuang): This is for testing purpose at this moment.
- // We use this message to pass the resulting PDF to the browser,
- // and the browser will save this PDF on the disk.
- did_page_params.data_size = buf_size;
- Send(new ViewHostMsg_DidPrintPage(routing_id(), did_page_params));
- } else {
- NOTREACHED() << "GetData() failed";
- }
- shared_buf.Unmap();
- } else {
- NOTREACHED() << "Buffer mapping failed";
- }
- } else {
- NOTREACHED() << "Buffer allocation failed";
- }
- } else {
- NOTREACHED() << "Buffer allocation failed";
+ // We only can use PDF in the renderer because Cairo needs to create a
+ // temporary file for a PostScript surface.
+ printing::NativeMetafile metafile(printing::NativeMetafile::PDF);
+ metafile.Init();
+
+ ViewMsg_PrintPage_Params print_page_params;
+ print_page_params.params = params.params;
+ const gfx::Size& canvas_size = prep_frame_view.GetPrintCanvasSize();
+ if (params.pages.empty()) {
+ for (int i = 0; i < page_count; ++i) {
+ print_page_params.page_number = i;
+ PrintPage(print_page_params, canvas_size, frame, &metafile);
+ }
+ } else {
+ for (size_t i = 0; i < params.pages.size(); ++i) {
+ print_page_params.page_number = params.pages[i];
+ PrintPage(print_page_params, canvas_size, frame, &metafile);
}
}
+
+ metafile.Close();
+
+ // Get the size of the resulting metafile.
+ unsigned int buf_size = metafile.GetDataSize();
+ DCHECK_GT(buf_size, 0u);
+
+ base::FileDescriptor fd;
+ int fd_in_browser = -1;
+
+ // Ask the browser to open a file for us.
+ if (!Send(new ViewHostMsg_AllocateTempFileForPrinting(&fd,
+ &fd_in_browser))) {
+ return;
+ }
+
+ if (!metafile.SaveTo(fd))
+ return;
+
+ // Tell the browser we've finished writing the file.
+ Send(new ViewHostMsg_TempFileForPrintingWritten(fd_in_browser));
}
void PrintWebViewHelper::PrintPage(const ViewMsg_PrintPage_Params& params,