summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/common/utility_messages_internal.h8
-rw-r--r--chrome/service/cloud_print/print_system_win.cc7
-rw-r--r--chrome/service/service_child_process_host.cc5
-rw-r--r--chrome/service/service_child_process_host.h2
-rw-r--r--chrome/service/service_utility_process_host.cc56
-rw-r--r--chrome/service/service_utility_process_host.h17
-rw-r--r--chrome/utility/utility_thread.cc10
-rw-r--r--chrome/utility/utility_thread.h2
8 files changed, 85 insertions, 22 deletions
diff --git a/chrome/common/utility_messages_internal.h b/chrome/common/utility_messages_internal.h
index 15bd8d6..18ba3c5 100644
--- a/chrome/common/utility_messages_internal.h
+++ b/chrome/common/utility_messages_internal.h
@@ -47,8 +47,9 @@ IPC_BEGIN_MESSAGES(Utility)
std::vector<unsigned char>) // encoded image contents
// Tell the utility process to render the given PDF into a metafile.
- IPC_MESSAGE_CONTROL4(UtilityMsg_RenderPDFPagesToMetafile,
+ IPC_MESSAGE_CONTROL5(UtilityMsg_RenderPDFPagesToMetafile,
base::PlatformFile, // PDF file
+ FilePath, // Location for output metafile
gfx::Rect, // Render Area
int, // DPI
std::vector<printing::PageRange>)
@@ -115,9 +116,8 @@ IPC_BEGIN_MESSAGES(UtilityHost)
IPC_MESSAGE_CONTROL0(UtilityHostMsg_DecodeImage_Failed)
// Reply when the utility process has succeeded in rendering the PDF.
- IPC_MESSAGE_CONTROL2(UtilityHostMsg_RenderPDFPagesToMetafile_Succeeded,
- printing::NativeMetafile, // Output metafile
- int) // Highest rendered page number
+ IPC_MESSAGE_CONTROL1(UtilityHostMsg_RenderPDFPagesToMetafile_Succeeded,
+ int) // Highest rendered page number
// Reply when an error occured rendering the PDF.
IPC_MESSAGE_CONTROL0(UtilityHostMsg_RenderPDFPagesToMetafile_Failed)
diff --git a/chrome/service/cloud_print/print_system_win.cc b/chrome/service/cloud_print/print_system_win.cc
index 9b71581..fe0d19f 100644
--- a/chrome/service/cloud_print/print_system_win.cc
+++ b/chrome/service/cloud_print/print_system_win.cc
@@ -503,7 +503,12 @@ class PrintSystemWin : public PrintSystem {
utility_host.release();
}
}
- static const int kPageCountPerBatch = 10;
+ // Some Cairo-generated PDFs from Chrome OS result in huge metafiles.
+ // So the PageCountPerBatch is set to 1 for now.
+ // TODO(sanjeevr): Figure out a smarter way to determine the pages per
+ // batch. Filed a bug to track this at
+ // http://code.google.com/p/chromium/issues/detail?id=57350.
+ static const int kPageCountPerBatch = 1;
int last_page_printed_;
PlatformJobId job_id_;
PrintSystem::JobSpooler::Delegate* delegate_;
diff --git a/chrome/service/service_child_process_host.cc b/chrome/service/service_child_process_host.cc
index c7cbea2e..00dfacc 100644
--- a/chrome/service/service_child_process_host.cc
+++ b/chrome/service/service_child_process_host.cc
@@ -22,13 +22,14 @@ ServiceChildProcessHost::~ServiceChildProcessHost() {
base::KillProcess(handle(), ResultCodes::NORMAL_EXIT, false);
}
-bool ServiceChildProcessHost::Launch(CommandLine* cmd_line) {
+bool ServiceChildProcessHost::Launch(CommandLine* cmd_line,
+ const FilePath& exposed_dir) {
#if !defined(OS_WIN)
// TODO(sanjeevr): Implement for non-Windows OSes.
NOTIMPLEMENTED();
return false;
#else // !defined(OS_WIN)
- set_handle(sandbox::StartProcessWithAccess(cmd_line, FilePath()));
+ set_handle(sandbox::StartProcessWithAccess(cmd_line, exposed_dir));
return (handle() != base::kNullProcessHandle);
#endif // !defined(OS_WIN)
}
diff --git a/chrome/service/service_child_process_host.h b/chrome/service/service_child_process_host.h
index 2743229..fe8b5df 100644
--- a/chrome/service/service_child_process_host.h
+++ b/chrome/service/service_child_process_host.h
@@ -23,7 +23,7 @@ class ServiceChildProcessHost : public ChildProcessHost,
explicit ServiceChildProcessHost(ProcessType type);
// Derived classes call this to launch the child process synchronously.
// TODO(sanjeevr): Determine whether we need to make the launch asynchronous.
- bool Launch(CommandLine* cmd_line);
+ bool Launch(CommandLine* cmd_line, const FilePath& exposed_dir);
};
#endif // CHROME_SERVICE_SERVICE_CHILD_PROCESS_HOST_H_
diff --git a/chrome/service/service_utility_process_host.cc b/chrome/service/service_utility_process_host.cc
index 21daaf6..6b2bdbbb 100644
--- a/chrome/service/service_utility_process_host.cc
+++ b/chrome/service/service_utility_process_host.cc
@@ -9,6 +9,7 @@
#include "base/file_util.h"
#include "base/message_loop.h"
#include "base/message_loop_proxy.h"
+#include "base/scoped_temp_dir.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/utility_messages.h"
#include "gfx/rect.h"
@@ -38,7 +39,15 @@ bool ServiceUtilityProcessHost::StartRenderPDFPagesToMetafile(
NOTIMPLEMENTED();
return false;
#else // !defined(OS_WIN)
- if (!StartProcess())
+ scratch_metafile_dir_.reset(new ScopedTempDir);
+ if (!scratch_metafile_dir_->CreateUniqueTempDir())
+ return false;
+ if (!file_util::CreateTemporaryFileInDir(scratch_metafile_dir_->path(),
+ &metafile_path_)) {
+ return false;
+ }
+
+ if (!StartProcess(scratch_metafile_dir_->path()))
return false;
ScopedHandle pdf_file(
@@ -60,13 +69,14 @@ bool ServiceUtilityProcessHost::StartRenderPDFPagesToMetafile(
waiting_for_reply_ = true;
return SendOnChannel(
new UtilityMsg_RenderPDFPagesToMetafile(pdf_file_in_utility_process,
+ metafile_path_,
render_area,
render_dpi,
page_ranges));
#endif // !defined(OS_WIN)
}
-bool ServiceUtilityProcessHost::StartProcess() {
+bool ServiceUtilityProcessHost::StartProcess(const FilePath& exposed_dir) {
// Name must be set or metrics_service will crash in any test which
// launches a UtilityProcessHost.
set_name(L"utility process");
@@ -85,7 +95,7 @@ bool ServiceUtilityProcessHost::StartProcess() {
cmd_line.AppendSwitchASCII(switches::kProcessChannelID, channel_id());
cmd_line.AppendSwitch(switches::kLang);
- return Launch(&cmd_line);
+ return Launch(&cmd_line, exposed_dir);
}
FilePath ServiceUtilityProcessHost::GetUtilityProcessCmd() {
@@ -110,6 +120,8 @@ void ServiceUtilityProcessHost::OnMessageReceived(const IPC::Message& message) {
#if defined(OS_WIN) // This hack is Windows-specific.
IPC_MESSAGE_HANDLER(UtilityHostMsg_PreCacheFont, OnPreCacheFont)
#endif
+ IPC_MESSAGE_HANDLER(UtilityHostMsg_RenderPDFPagesToMetafile_Succeeded,
+ OnRenderPDFPagesToMetafileSucceeded)
IPC_MESSAGE_UNHANDLED(msg_is_ok__ = MessageForClient(message))
IPC_END_MESSAGE_MAP_EX()
}
@@ -130,16 +142,46 @@ void ServiceUtilityProcessHost::OnPreCacheFont(LOGFONT font) {
}
#endif // OS_WIN
+void ServiceUtilityProcessHost::OnRenderPDFPagesToMetafileSucceeded(
+ int highest_rendered_page_number) {
+ DCHECK(waiting_for_reply_);
+ // If the metafile was successfully created, we need to take our hands off the
+ // scratch metafile directory. The client will delete it when it is done with
+ // metafile.
+ scratch_metafile_dir_->Take();
+ client_message_loop_proxy_->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(client_.get(),
+ &Client::MetafileAvailable,
+ metafile_path_,
+ highest_rendered_page_number));
+ waiting_for_reply_ = false;
+}
void ServiceUtilityProcessHost::Client::OnMessageReceived(
const IPC::Message& message) {
IPC_BEGIN_MESSAGE_MAP(ServiceUtilityProcessHost, message)
-#if defined(OS_WIN)
- IPC_MESSAGE_HANDLER(UtilityHostMsg_RenderPDFPagesToMetafile_Succeeded,
- Client::OnRenderPDFPagesToMetafileSucceeded)
-#endif // OS_WIN
IPC_MESSAGE_HANDLER(UtilityHostMsg_RenderPDFPagesToMetafile_Failed,
Client::OnRenderPDFPagesToMetafileFailed)
IPC_END_MESSAGE_MAP_EX()
}
+void ServiceUtilityProcessHost::Client::MetafileAvailable(
+ const FilePath& metafile_path,
+ int highest_rendered_page_number) {
+ // The metafile was created in a temp folder which needs to get deleted after
+ // we have processed it.
+ ScopedTempDir scratch_metafile_dir;
+ scratch_metafile_dir.Set(metafile_path.DirName());
+#if defined(OS_WIN)
+ printing::NativeMetafile metafile;
+ if (!metafile.CreateFromFile(metafile_path)) {
+ OnRenderPDFPagesToMetafileFailed();
+ } else {
+ OnRenderPDFPagesToMetafileSucceeded(metafile, highest_rendered_page_number);
+ // Close it so that ScopedTempDir can delete the folder.
+ metafile.CloseEmf();
+ }
+#endif // defined(OS_WIN)
+}
+
diff --git a/chrome/service/service_utility_process_host.h b/chrome/service/service_utility_process_host.h
index c069426..477e945 100644
--- a/chrome/service/service_utility_process_host.h
+++ b/chrome/service/service_utility_process_host.h
@@ -15,6 +15,7 @@
#include <vector>
#include "base/basictypes.h"
+#include "base/file_path.h"
#include "base/ref_counted.h"
#include "base/task.h"
#include "ipc/ipc_channel.h"
@@ -22,7 +23,7 @@
#include "printing/native_metafile.h"
class CommandLine;
-class FilePath;
+class ScopedTempDir;
namespace base {
class MessageLoopProxy;
@@ -67,6 +68,9 @@ class ServiceUtilityProcessHost : public ServiceChildProcessHost {
friend class ServiceUtilityProcessHost;
void OnMessageReceived(const IPC::Message& message);
+ // Invoked when a metafile file is ready.
+ void MetafileAvailable(const FilePath& metafile_path,
+ int highest_rendered_page_number);
DISALLOW_COPY_AND_ASSIGN(Client);
};
@@ -100,21 +104,28 @@ class ServiceUtilityProcessHost : public ServiceChildProcessHost {
private:
// Starts a process. Returns true iff it succeeded.
- bool StartProcess();
+ bool StartProcess(const FilePath& exposed_dir);
// IPC messages:
void OnMessageReceived(const IPC::Message& message);
+ // Called when at least one page in the specified PDF has been rendered
+ // successfully into metafile_path_;
+ void OnRenderPDFPagesToMetafileSucceeded(int highest_rendered_page_number);
+ // Any other messages to be handled by the client.
bool MessageForClient(const IPC::Message& message);
#if defined(OS_WIN) // This hack is Windows-specific.
void OnPreCacheFont(LOGFONT font);
#endif // defined(OS_WIN)
-
// A pointer to our client interface, who will be informed of progress.
scoped_refptr<Client> client_;
scoped_refptr<base::MessageLoopProxy> client_message_loop_proxy_;
bool waiting_for_reply_;
+ // The path to the temp file where the metafile will be written to.
+ FilePath metafile_path_;
+ // The temporary folder created for the metafile.
+ scoped_ptr<ScopedTempDir> scratch_metafile_dir_;
DISALLOW_COPY_AND_ASSIGN(ServiceUtilityProcessHost);
};
diff --git a/chrome/utility/utility_thread.cc b/chrome/utility/utility_thread.cc
index ac8de68..4392557 100644
--- a/chrome/utility/utility_thread.cc
+++ b/chrome/utility/utility_thread.cc
@@ -119,6 +119,7 @@ void UtilityThread::OnDecodeImage(
void UtilityThread::OnRenderPDFPagesToMetafile(
base::PlatformFile pdf_file,
+ const FilePath& metafile_path,
const gfx::Rect& render_area,
int render_dpi,
const std::vector<printing::PageRange>& page_ranges) {
@@ -126,11 +127,11 @@ void UtilityThread::OnRenderPDFPagesToMetafile(
#if defined(OS_WIN)
printing::NativeMetafile metafile;
int highest_rendered_page_number = 0;
- succeeded = RenderPDFToWinMetafile(pdf_file, render_area, render_dpi,
- page_ranges, &metafile,
+ succeeded = RenderPDFToWinMetafile(pdf_file, metafile_path, render_area,
+ render_dpi, page_ranges, &metafile,
&highest_rendered_page_number);
if (succeeded) {
- Send(new UtilityHostMsg_RenderPDFPagesToMetafile_Succeeded(metafile,
+ Send(new UtilityHostMsg_RenderPDFPagesToMetafile_Succeeded(
highest_rendered_page_number));
}
#endif // defined(OS_WIN)
@@ -189,6 +190,7 @@ DWORD WINAPI UtilityProcess_GetFontDataPatch(
bool UtilityThread::RenderPDFToWinMetafile(
base::PlatformFile pdf_file,
+ const FilePath& metafile_path,
const gfx::Rect& render_area,
int render_dpi,
const std::vector<printing::PageRange>& page_ranges,
@@ -242,7 +244,7 @@ bool UtilityThread::RenderPDFToWinMetafile(
if (!get_info_proc(&buffer.front(), buffer.size(), &total_page_count, NULL))
return false;
- metafile->CreateDc(NULL, NULL);
+ metafile->CreateFileBackedDc(NULL, NULL, metafile_path);
// Since we created the metafile using the screen DPI (but we actually want
// the PDF DLL to print using the passed in render_dpi, we apply the following
// transformation.
diff --git a/chrome/utility/utility_thread.h b/chrome/utility/utility_thread.h
index a92c08b..36419aa 100644
--- a/chrome/utility/utility_thread.h
+++ b/chrome/utility/utility_thread.h
@@ -53,6 +53,7 @@ class UtilityThread : public ChildThread {
// IPC to render a PDF into a platform metafile.
void OnRenderPDFPagesToMetafile(
base::PlatformFile pdf_file,
+ const FilePath& metafile_path,
const gfx::Rect& render_area,
int render_dpi,
const std::vector<printing::PageRange>& page_ranges);
@@ -62,6 +63,7 @@ class UtilityThread : public ChildThread {
// |highest_rendered_page_number| is set to -1 on failure to render any page.
bool RenderPDFToWinMetafile(
base::PlatformFile pdf_file,
+ const FilePath& metafile_path,
const gfx::Rect& render_area,
int render_dpi,
const std::vector<printing::PageRange>& page_ranges,