This source file includes following definitions.
- pwg_file_
- GetPwgPath
- GetPdfPath
- GetPdfForProcess
- GetPwgForProcess
- Init
- IsValid
- bitmap_settings_
- Convert
- OnProcessCrashed
- OnMessageReceived
- OnProcessStarted
- OnSucceeded
- OnFailed
- OnFilesReadyOnUIThread
- StartProcessOnIOThread
- RunCallback
- RunCallbackOnUIThread
- Start
- CreateDefault
#include "chrome/browser/local_discovery/pwg_raster_converter.h"
#include "base/bind_helpers.h"
#include "base/cancelable_callback.h"
#include "base/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
#include "chrome/common/chrome_utility_messages.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/utility_process_host.h"
#include "content/public/browser/utility_process_host_client.h"
namespace local_discovery {
namespace {
using content::BrowserThread;
class FileHandlers {
public:
FileHandlers() : pdf_file_(base::kInvalidPlatformFileValue),
pwg_file_(base::kInvalidPlatformFileValue) { }
~FileHandlers() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
if (pdf_file_ != base::kInvalidPlatformFileValue)
base::ClosePlatformFile(pdf_file_);
if (pwg_file_ != base::kInvalidPlatformFileValue)
base::ClosePlatformFile(pwg_file_);
}
void Init(base::RefCountedMemory* data);
bool IsValid();
base::FilePath GetPwgPath() const {
return temp_dir_.path().AppendASCII("output.pwg");
}
base::FilePath GetPdfPath() const {
return temp_dir_.path().AppendASCII("input.pdf");
}
IPC::PlatformFileForTransit GetPdfForProcess(base::ProcessHandle process) {
DCHECK_NE(pdf_file_, base::kInvalidPlatformFileValue);
IPC::PlatformFileForTransit transit =
IPC::GetFileHandleForProcess(pdf_file_, process, true);
pdf_file_ = base::kInvalidPlatformFileValue;
return transit;
}
IPC::PlatformFileForTransit GetPwgForProcess(base::ProcessHandle process) {
DCHECK_NE(pwg_file_, base::kInvalidPlatformFileValue);
IPC::PlatformFileForTransit transit =
IPC::GetFileHandleForProcess(pwg_file_, process, true);
pwg_file_ = base::kInvalidPlatformFileValue;
return transit;
}
private:
base::ScopedTempDir temp_dir_;
base::PlatformFile pdf_file_;
base::PlatformFile pwg_file_;
};
void FileHandlers::Init(base::RefCountedMemory* data) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
if (!temp_dir_.CreateUniqueTempDir()) {
return;
}
if (static_cast<int>(data->size()) !=
base::WriteFile(GetPdfPath(), data->front_as<char>(), data->size())) {
return;
}
pdf_file_ = base::CreatePlatformFile(GetPdfPath(), base::PLATFORM_FILE_OPEN |
base::PLATFORM_FILE_READ,
NULL, NULL);
pwg_file_ = base::CreatePlatformFile(GetPwgPath(),
base::PLATFORM_FILE_CREATE_ALWAYS |
base::PLATFORM_FILE_APPEND, NULL, NULL);
}
bool FileHandlers::IsValid() {
return pdf_file_ != base::kInvalidPlatformFileValue &&
pwg_file_ != base::kInvalidPlatformFileValue;
}
class PwgUtilityProcessHostClient : public content::UtilityProcessHostClient {
public:
explicit PwgUtilityProcessHostClient(
const printing::PdfRenderSettings& settings,
const printing::PwgRasterSettings& bitmap_settings);
void Convert(base::RefCountedMemory* data,
const PWGRasterConverter::ResultCallback& callback);
virtual void OnProcessCrashed(int exit_code) OVERRIDE;
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
private:
virtual ~PwgUtilityProcessHostClient();
void OnProcessStarted();
void OnSucceeded();
void OnFailed();
void RunCallback(bool success);
void StartProcessOnIOThread();
void RunCallbackOnUIThread(bool success);
void OnFilesReadyOnUIThread();
scoped_ptr<FileHandlers> files_;
printing::PdfRenderSettings settings_;
printing::PwgRasterSettings bitmap_settings_;
PWGRasterConverter::ResultCallback callback_;
base::WeakPtr<content::UtilityProcessHost> utility_process_host_;
DISALLOW_COPY_AND_ASSIGN(PwgUtilityProcessHostClient);
};
PwgUtilityProcessHostClient::PwgUtilityProcessHostClient(
const printing::PdfRenderSettings& settings,
const printing::PwgRasterSettings& bitmap_settings)
: settings_(settings), bitmap_settings_(bitmap_settings) {}
PwgUtilityProcessHostClient::~PwgUtilityProcessHostClient() {
BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, files_.release());
}
void PwgUtilityProcessHostClient::Convert(
base::RefCountedMemory* data,
const PWGRasterConverter::ResultCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
callback_ = callback;
CHECK(!files_);
files_.reset(new FileHandlers());
BrowserThread::PostTaskAndReply(
BrowserThread::FILE, FROM_HERE,
base::Bind(&FileHandlers::Init, base::Unretained(files_.get()),
make_scoped_refptr(data)),
base::Bind(&PwgUtilityProcessHostClient::OnFilesReadyOnUIThread, this));
}
void PwgUtilityProcessHostClient::OnProcessCrashed(int exit_code) {
OnFailed();
}
bool PwgUtilityProcessHostClient::OnMessageReceived(
const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(PwgUtilityProcessHostClient, message)
IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ProcessStarted, OnProcessStarted)
IPC_MESSAGE_HANDLER(
ChromeUtilityHostMsg_RenderPDFPagesToPWGRaster_Succeeded, OnSucceeded)
IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_RenderPDFPagesToPWGRaster_Failed,
OnFailed)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void PwgUtilityProcessHostClient::OnProcessStarted() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
if (!utility_process_host_) {
RunCallbackOnUIThread(false);
return;
}
base::ProcessHandle process = utility_process_host_->GetData().handle;
utility_process_host_->Send(new ChromeUtilityMsg_RenderPDFPagesToPWGRaster(
files_->GetPdfForProcess(process),
settings_,
bitmap_settings_,
files_->GetPwgForProcess(process)));
utility_process_host_.reset();
}
void PwgUtilityProcessHostClient::OnSucceeded() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
RunCallback(true);
}
void PwgUtilityProcessHostClient::OnFailed() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
RunCallback(false);
}
void PwgUtilityProcessHostClient::OnFilesReadyOnUIThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (!files_->IsValid()) {
RunCallbackOnUIThread(false);
return;
}
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&PwgUtilityProcessHostClient::StartProcessOnIOThread, this));
}
void PwgUtilityProcessHostClient::StartProcessOnIOThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
utility_process_host_ =
content::UtilityProcessHost::Create(
this,
base::MessageLoop::current()->message_loop_proxy())->AsWeakPtr();
utility_process_host_->Send(new ChromeUtilityMsg_StartupPing);
}
void PwgUtilityProcessHostClient::RunCallback(bool success) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&PwgUtilityProcessHostClient::RunCallbackOnUIThread, this,
success));
}
void PwgUtilityProcessHostClient::RunCallbackOnUIThread(bool success) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (!callback_.is_null()) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(callback_, success,
files_->GetPwgPath()));
callback_.Reset();
}
}
class PWGRasterConverterImpl : public PWGRasterConverter {
public:
PWGRasterConverterImpl();
virtual ~PWGRasterConverterImpl();
virtual void Start(base::RefCountedMemory* data,
const printing::PdfRenderSettings& conversion_settings,
const printing::PwgRasterSettings& bitmap_settings,
const ResultCallback& callback) OVERRIDE;
private:
scoped_refptr<PwgUtilityProcessHostClient> utility_client_;
base::CancelableCallback<ResultCallback::RunType> callback_;
DISALLOW_COPY_AND_ASSIGN(PWGRasterConverterImpl);
};
PWGRasterConverterImpl::PWGRasterConverterImpl() {
}
PWGRasterConverterImpl::~PWGRasterConverterImpl() {
}
void PWGRasterConverterImpl::Start(
base::RefCountedMemory* data,
const printing::PdfRenderSettings& conversion_settings,
const printing::PwgRasterSettings& bitmap_settings,
const ResultCallback& callback) {
callback_.Reset(callback);
utility_client_ =
new PwgUtilityProcessHostClient(conversion_settings, bitmap_settings);
utility_client_->Convert(data, callback_.callback());
}
}
scoped_ptr<PWGRasterConverter> PWGRasterConverter::CreateDefault() {
return scoped_ptr<PWGRasterConverter>(new PWGRasterConverterImpl());
}
}