Merge remote-tracking branch 'origin/master' into renaesop_master

This commit is contained in:
Kevin Sawicki 2017-05-18 10:08:40 -07:00
commit 84a9b6a42d
336 changed files with 16704 additions and 2418 deletions

View file

@ -92,12 +92,12 @@ CertificateManagerModel::CertificateManagerModel(
CertificateManagerModel::~CertificateManagerModel() {
}
int CertificateManagerModel::ImportFromPKCS12(net::CryptoModule* module,
int CertificateManagerModel::ImportFromPKCS12(PK11SlotInfo* slot_info,
const std::string& data,
const base::string16& password,
bool is_extractable,
net::CertificateList* imported_certs) {
return cert_db_->ImportFromPKCS12(module, data, password,
return cert_db_->ImportFromPKCS12(slot_info, data, password,
is_extractable, imported_certs);
}

View file

@ -44,7 +44,7 @@ class CertificateManagerModel {
// |data|, using the given |password|. If |is_extractable| is false,
// mark the private key as unextractable from the module.
// Returns a net error code on failure.
int ImportFromPKCS12(net::CryptoModule* module,
int ImportFromPKCS12(PK11SlotInfo* slot_info,
const std::string& data,
const base::string16& password,
bool is_extractable,

View file

@ -8,6 +8,8 @@
#include <set>
#include <sstream>
using base::PlatformThreadRef;
#include "base/hash.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"

View file

@ -18,10 +18,9 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/common/chrome_utility_messages.h"
#include "chrome/common/print_messages.h"
#include "chrome/common/chrome_utility_printing_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"
@ -30,13 +29,13 @@
#include "printing/pdf_render_settings.h"
#include "ui/base/l10n/l10n_util.h"
using content::BrowserThread;
namespace printing {
namespace {
using content::BrowserThread;
class PdfToEmfConverterImpl;
class PdfConverterImpl;
// Allows to delete temporary directory after all temporary files created inside
// are closed. Windows cannot delete directory with opened files. Directory is
@ -59,8 +58,8 @@ class RefCountedTempDir
DISALLOW_COPY_AND_ASSIGN(RefCountedTempDir);
};
typedef std::unique_ptr<base::File, BrowserThread::DeleteOnFileThread>
ScopedTempFile;
using ScopedTempFile =
std::unique_ptr<base::File, BrowserThread::DeleteOnFileThread>;
// Wrapper for Emf to keep only file handle in memory, and load actual data only
// on playback. Emf::InitFromFile() can play metafile directly from disk, but it
@ -74,21 +73,39 @@ class LazyEmf : public MetafilePlayer {
}
~LazyEmf() override { Close(); }
protected:
// MetafilePlayer:
bool SafePlayback(HDC hdc) const override;
bool GetDataAsVector(std::vector<char>* buffer) const override;
bool SaveTo(base::File* file) const override;
private:
void Close() const;
bool LoadEmf(Emf* emf) const;
private:
mutable scoped_refptr<RefCountedTempDir> temp_dir_;
mutable ScopedTempFile file_; // Mutable because of consts in base class.
bool GetDataAsVector(std::vector<char>* buffer) const override;
bool SaveTo(base::File* file) const override;
DISALLOW_COPY_AND_ASSIGN(LazyEmf);
};
// Converts PDF into EMF.
// Postscript metafile subclass to override SafePlayback.
class PostScriptMetaFile : public LazyEmf {
public:
PostScriptMetaFile(const scoped_refptr<RefCountedTempDir>& temp_dir,
ScopedTempFile file)
: LazyEmf(temp_dir, std::move(file)) {}
~PostScriptMetaFile() override;
protected:
// MetafilePlayer:
bool SafePlayback(HDC hdc) const override;
DISALLOW_COPY_AND_ASSIGN(PostScriptMetaFile);
};
// Class for converting PDF to another format for printing (Emf, Postscript).
// Class uses 3 threads: UI, IO and FILE.
// Internal workflow is following:
// 1. Create instance on the UI thread. (files_, settings_,)
@ -101,36 +118,33 @@ class LazyEmf : public MetafilePlayer {
//
// All these steps work sequentially, so no data should be accessed
// simultaneously by several threads.
class PdfToEmfUtilityProcessHostClient
class PdfConverterUtilityProcessHostClient
: public content::UtilityProcessHostClient {
public:
PdfToEmfUtilityProcessHostClient(
base::WeakPtr<PdfToEmfConverterImpl> converter,
PdfConverterUtilityProcessHostClient(
base::WeakPtr<PdfConverterImpl> converter,
const PdfRenderSettings& settings);
void Start(const scoped_refptr<base::RefCountedMemory>& data,
bool print_text_with_gdi,
const PdfToEmfConverter::StartCallback& start_callback);
const PdfConverter::StartCallback& start_callback);
void GetPage(int page_number,
const PdfToEmfConverter::GetPageCallback& get_page_callback);
const PdfConverter::GetPageCallback& get_page_callback);
void Stop();
// UtilityProcessHostClient implementation.
void OnProcessCrashed(int exit_code) override;
void OnProcessLaunchFailed(int exit_code) override;
// Needs to be public to handle ChromeUtilityHostMsg_PreCacheFontCharacters
// sync message replies.
bool Send(IPC::Message* msg);
// UtilityProcessHostClient implementation.
void OnProcessCrashed(int exit_code) override;
void OnProcessLaunchFailed(int exit_code) override;
bool OnMessageReceived(const IPC::Message& message) override;
private:
protected:
class GetPageCallbackData {
public:
GetPageCallbackData(int page_number,
PdfToEmfConverter::GetPageCallback callback)
GetPageCallbackData(int page_number, PdfConverter::GetPageCallback callback)
: page_number_(page_number), callback_(callback) {}
GetPageCallbackData(GetPageCallbackData&& other) {
@ -140,45 +154,62 @@ class PdfToEmfUtilityProcessHostClient
GetPageCallbackData& operator=(GetPageCallbackData&& rhs) {
page_number_ = rhs.page_number_;
callback_ = rhs.callback_;
emf_ = std::move(rhs.emf_);
file_ = std::move(rhs.file_);
return *this;
}
int page_number() const { return page_number_; }
const PdfToEmfConverter::GetPageCallback& callback() const {
return callback_;
}
ScopedTempFile TakeEmf() { return std::move(emf_); }
void set_emf(ScopedTempFile emf) { emf_ = std::move(emf); }
const PdfConverter::GetPageCallback& callback() const { return callback_; }
ScopedTempFile TakeFile() { return std::move(file_); }
void set_file(ScopedTempFile file) { file_ = std::move(file); }
private:
int page_number_;
PdfToEmfConverter::GetPageCallback callback_;
ScopedTempFile emf_;
PdfConverter::GetPageCallback callback_;
ScopedTempFile file_;
DISALLOW_COPY_AND_ASSIGN(GetPageCallbackData);
};
~PdfToEmfUtilityProcessHostClient() override;
~PdfConverterUtilityProcessHostClient() override;
// Message handlers.
bool OnMessageReceived(const IPC::Message& message) override;
// Helper functions: must be overridden by subclasses
// Set the process name
virtual base::string16 GetName() const;
// Create a metafileplayer subclass file from a temporary file.
virtual std::unique_ptr<MetafilePlayer> GetFileFromTemp(
std::unique_ptr<base::File, content::BrowserThread::DeleteOnFileThread>
temp_file);
// Send the messages to Start, GetPage, and Stop.
virtual void SendStartMessage(IPC::PlatformFileForTransit transit);
virtual void SendGetPageMessage(int page_number,
IPC::PlatformFileForTransit transit);
virtual void SendStopMessage();
// Message handlers:
void OnPageCount(int page_count);
void OnPageDone(bool success, float scale_factor);
void OnFailed();
void OnTempPdfReady(ScopedTempFile pdf);
void OnTempFileReady(GetPageCallbackData* callback_data,
ScopedTempFile temp_file);
// Additional message handler needed for Pdf to Emf
void OnPreCacheFontCharacters(const LOGFONT& log_font,
const base::string16& characters);
void OnFailed();
void OnTempPdfReady(bool print_text_with_gdi, ScopedTempFile pdf);
void OnTempEmfReady(GetPageCallbackData* callback_data, ScopedTempFile emf);
scoped_refptr<RefCountedTempDir> temp_dir_;
// Used to suppress callbacks after PdfToEmfConverterImpl is deleted.
base::WeakPtr<PdfToEmfConverterImpl> converter_;
// Used to suppress callbacks after PdfConverter is deleted.
base::WeakPtr<PdfConverterImpl> converter_;
PdfRenderSettings settings_;
// Document loaded callback.
PdfToEmfConverter::StartCallback start_callback_;
PdfConverter::StartCallback start_callback_;
// Process host for IPC.
base::WeakPtr<content::UtilityProcessHost> utility_process_host_;
@ -186,22 +217,37 @@ class PdfToEmfUtilityProcessHostClient
// Queue of callbacks for GetPage() requests. Utility process should reply
// with PageDone in the same order as requests were received.
// Use containers that keeps element pointers valid after push() and pop().
typedef std::queue<GetPageCallbackData> GetPageCallbacks;
using GetPageCallbacks = std::queue<GetPageCallbackData>;
GetPageCallbacks get_page_callbacks_;
DISALLOW_COPY_AND_ASSIGN(PdfToEmfUtilityProcessHostClient);
DISALLOW_COPY_AND_ASSIGN(PdfConverterUtilityProcessHostClient);
};
class PdfToEmfConverterImpl : public PdfToEmfConverter {
public:
PdfToEmfConverterImpl();
std::unique_ptr<MetafilePlayer>
PdfConverterUtilityProcessHostClient::GetFileFromTemp(
std::unique_ptr<base::File, content::BrowserThread::DeleteOnFileThread>
temp_file) {
if (settings_.mode == PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2 ||
settings_.mode == PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3) {
return base::MakeUnique<PostScriptMetaFile>(temp_dir_,
std::move(temp_file));
}
return base::MakeUnique<LazyEmf>(temp_dir_, std::move(temp_file));
}
~PdfToEmfConverterImpl() override;
class PdfConverterImpl : public PdfConverter {
public:
PdfConverterImpl();
~PdfConverterImpl() override;
base::WeakPtr<PdfConverterImpl> GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
void Start(const scoped_refptr<base::RefCountedMemory>& data,
const PdfRenderSettings& conversion_settings,
bool print_text_with_gdi,
const StartCallback& start_callback) override;
const StartCallback& start_callback);
void GetPage(int page_number,
const GetPageCallback& get_page_callback) override;
@ -209,11 +255,17 @@ class PdfToEmfConverterImpl : public PdfToEmfConverter {
// Helps to cancel callbacks if this object is destroyed.
void RunCallback(const base::Closure& callback);
private:
scoped_refptr<PdfToEmfUtilityProcessHostClient> utility_client_;
base::WeakPtrFactory<PdfToEmfConverterImpl> weak_ptr_factory_;
void Start(
const scoped_refptr<PdfConverterUtilityProcessHostClient>& utility_client,
const scoped_refptr<base::RefCountedMemory>& data,
const StartCallback& start_callback);
DISALLOW_COPY_AND_ASSIGN(PdfToEmfConverterImpl);
private:
scoped_refptr<PdfConverterUtilityProcessHostClient> utility_client_;
base::WeakPtrFactory<PdfConverterImpl> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(PdfConverterImpl);
};
ScopedTempFile CreateTempFile(scoped_refptr<RefCountedTempDir>* temp_dir) {
@ -260,10 +312,10 @@ ScopedTempFile CreateTempPdfFile(
bool LazyEmf::SafePlayback(HDC hdc) const {
Emf emf;
bool result = LoadEmf(&emf) && emf.SafePlayback(hdc);
// TODO(vitalybuka): Fix destruction of metafiles. For some reasons
// instances of Emf are not deleted. crbug.com/411683
// TODO(thestig): Fix destruction of metafiles. For some reasons
// instances of Emf are not deleted. https://crbug.com/260806
// It's known that the Emf going to be played just once to a printer. So just
// release file here.
// release |file_| here.
Close();
return result;
}
@ -280,7 +332,7 @@ bool LazyEmf::SaveTo(base::File* file) const {
void LazyEmf::Close() const {
file_.reset();
temp_dir_ = NULL;
temp_dir_ = nullptr;
}
bool LazyEmf::LoadEmf(Emf* emf) const {
@ -294,24 +346,55 @@ bool LazyEmf::LoadEmf(Emf* emf) const {
return emf->InitFromData(data.data(), data.size());
}
PdfToEmfUtilityProcessHostClient::PdfToEmfUtilityProcessHostClient(
base::WeakPtr<PdfToEmfConverterImpl> converter,
PostScriptMetaFile::~PostScriptMetaFile() {
}
bool PostScriptMetaFile::SafePlayback(HDC hdc) const {
// TODO(thestig): Fix destruction of metafiles. For some reasons
// instances of Emf are not deleted. https://crbug.com/260806
// It's known that the Emf going to be played just once to a printer. So just
// release |file_| before returning.
Emf emf;
if (!LoadEmf(&emf)) {
Close();
return false;
}
{
// Ensure enumerator destruction before calling Close() below.
Emf::Enumerator emf_enum(emf, nullptr, nullptr);
for (const Emf::Record& record : emf_enum) {
auto* emf_record = record.record();
if (emf_record->iType != EMR_GDICOMMENT)
continue;
const EMRGDICOMMENT* comment =
reinterpret_cast<const EMRGDICOMMENT*>(emf_record);
const char* data = reinterpret_cast<const char*>(comment->Data);
const uint16_t* ptr = reinterpret_cast<const uint16_t*>(data);
int ret = ExtEscape(hdc, PASSTHROUGH, 2 + *ptr, data, 0, nullptr);
DCHECK_EQ(*ptr, ret);
}
}
Close();
return true;
}
PdfConverterUtilityProcessHostClient::PdfConverterUtilityProcessHostClient(
base::WeakPtr<PdfConverterImpl> converter,
const PdfRenderSettings& settings)
: converter_(converter), settings_(settings) {
}
: converter_(converter), settings_(settings) {}
PdfToEmfUtilityProcessHostClient::~PdfToEmfUtilityProcessHostClient() {
}
PdfConverterUtilityProcessHostClient::~PdfConverterUtilityProcessHostClient() {}
void PdfToEmfUtilityProcessHostClient::Start(
void PdfConverterUtilityProcessHostClient::Start(
const scoped_refptr<base::RefCountedMemory>& data,
bool print_text_with_gdi,
const PdfToEmfConverter::StartCallback& start_callback) {
const PdfConverter::StartCallback& start_callback) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&PdfToEmfUtilityProcessHostClient::Start, this, data,
print_text_with_gdi, start_callback));
base::Bind(&PdfConverterUtilityProcessHostClient::Start, this, data,
start_callback));
return;
}
@ -324,50 +407,41 @@ void PdfToEmfUtilityProcessHostClient::Start(
utility_process_host_ = content::UtilityProcessHost::Create(
this, base::ThreadTaskRunnerHandle::Get())
->AsWeakPtr();
utility_process_host_->SetName(base::ASCIIToUTF16(
"IDS_UTILITY_PROCESS_EMF_CONVERTOR_NAME"));
utility_process_host_->SetName(GetName());
BrowserThread::PostTaskAndReplyWithResult(
BrowserThread::FILE, FROM_HERE,
base::Bind(&CreateTempPdfFile, data, &temp_dir_),
base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempPdfReady, this,
print_text_with_gdi));
base::Bind(&PdfConverterUtilityProcessHostClient::OnTempPdfReady, this));
}
void PdfToEmfUtilityProcessHostClient::OnTempPdfReady(bool print_text_with_gdi,
ScopedTempFile pdf) {
void PdfConverterUtilityProcessHostClient::OnTempPdfReady(ScopedTempFile pdf) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!utility_process_host_ || !pdf)
return OnFailed();
// Should reply with OnPageCount().
Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles(
IPC::GetPlatformFileForTransit(pdf->GetPlatformFile(), false), settings_,
print_text_with_gdi));
SendStartMessage(
IPC::GetPlatformFileForTransit(pdf->GetPlatformFile(), false));
}
void PdfToEmfUtilityProcessHostClient::OnPageCount(int page_count) {
void PdfConverterUtilityProcessHostClient::OnPageCount(int page_count) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (start_callback_.is_null())
return OnFailed();
BrowserThread::PostTask(BrowserThread::UI,
FROM_HERE,
base::Bind(&PdfToEmfConverterImpl::RunCallback,
converter_,
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(&PdfConverterImpl::RunCallback, converter_,
base::Bind(start_callback_, page_count)));
start_callback_.Reset();
}
void PdfToEmfUtilityProcessHostClient::GetPage(
void PdfConverterUtilityProcessHostClient::GetPage(
int page_number,
const PdfToEmfConverter::GetPageCallback& get_page_callback) {
const PdfConverter::GetPageCallback& get_page_callback) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
base::Bind(&PdfToEmfUtilityProcessHostClient::GetPage,
this,
page_number,
get_page_callback));
BrowserThread::IO, FROM_HERE,
base::Bind(&PdfConverterUtilityProcessHostClient::GetPage, this,
page_number, get_page_callback));
return;
}
@ -378,55 +452,84 @@ void PdfToEmfUtilityProcessHostClient::GetPage(
return OnFailed();
BrowserThread::PostTaskAndReplyWithResult(
BrowserThread::FILE,
FROM_HERE,
base::Bind(&CreateTempFile, &temp_dir_),
base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempEmfReady,
this,
BrowserThread::FILE, FROM_HERE, base::Bind(&CreateTempFile, &temp_dir_),
base::Bind(&PdfConverterUtilityProcessHostClient::OnTempFileReady, this,
&get_page_callbacks_.back()));
}
void PdfToEmfUtilityProcessHostClient::OnTempEmfReady(
void PdfConverterUtilityProcessHostClient::OnTempFileReady(
GetPageCallbackData* callback_data,
ScopedTempFile emf) {
ScopedTempFile temp_file) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!utility_process_host_ || !emf)
if (!utility_process_host_ || !temp_file)
return OnFailed();
IPC::PlatformFileForTransit transit =
IPC::GetPlatformFileForTransit(emf->GetPlatformFile(), false);
callback_data->set_emf(std::move(emf));
IPC::GetPlatformFileForTransit(temp_file->GetPlatformFile(), false);
callback_data->set_file(std::move(temp_file));
// Should reply with OnPageDone().
Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage(
callback_data->page_number(), transit));
SendGetPageMessage(callback_data->page_number(), transit);
}
void PdfToEmfUtilityProcessHostClient::OnPageDone(bool success,
float scale_factor) {
void PdfConverterUtilityProcessHostClient::OnPageDone(bool success,
float scale_factor) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (get_page_callbacks_.empty())
return OnFailed();
GetPageCallbackData& data = get_page_callbacks_.front();
std::unique_ptr<MetafilePlayer> emf;
std::unique_ptr<MetafilePlayer> file;
if (success) {
ScopedTempFile temp_emf = data.TakeEmf();
if (!temp_emf) // Unexpected message from utility process.
ScopedTempFile temp_file = data.TakeFile();
if (!temp_file) // Unexpected message from utility process.
return OnFailed();
emf = base::MakeUnique<LazyEmf>(temp_dir_, std::move(temp_emf));
file = GetFileFromTemp(std::move(temp_file));
}
BrowserThread::PostTask(BrowserThread::UI,
FROM_HERE,
base::Bind(&PdfToEmfConverterImpl::RunCallback,
converter_,
base::Bind(data.callback(),
data.page_number(),
scale_factor,
base::Passed(&emf))));
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&PdfConverterImpl::RunCallback, converter_,
base::Bind(data.callback(), data.page_number(), scale_factor,
base::Passed(&file))));
get_page_callbacks_.pop();
}
void PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters(
void PdfConverterUtilityProcessHostClient::Stop() {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&PdfConverterUtilityProcessHostClient::Stop, this));
return;
}
SendStopMessage();
}
void PdfConverterUtilityProcessHostClient::OnProcessCrashed(int exit_code) {
OnFailed();
}
void PdfConverterUtilityProcessHostClient::OnProcessLaunchFailed(
int exit_code) {
OnFailed();
}
bool PdfConverterUtilityProcessHostClient::Send(IPC::Message* msg) {
if (utility_process_host_)
return utility_process_host_->Send(msg);
delete msg;
return false;
}
void PdfConverterUtilityProcessHostClient::OnFailed() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!start_callback_.is_null())
OnPageCount(0);
while (!get_page_callbacks_.empty())
OnPageDone(false, 0.0f);
utility_process_host_.reset();
}
void PdfConverterUtilityProcessHostClient::OnPreCacheFontCharacters(
const LOGFONT& font,
const base::string16& str) {
// TODO(scottmg): pdf/ppapi still require the renderer to be able to precache
@ -458,29 +561,10 @@ void PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters(
DeleteEnhMetaFile(metafile);
}
void PdfToEmfUtilityProcessHostClient::Stop() {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
base::Bind(&PdfToEmfUtilityProcessHostClient::Stop, this));
return;
}
Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop());
}
void PdfToEmfUtilityProcessHostClient::OnProcessCrashed(int exit_code) {
OnFailed();
}
void PdfToEmfUtilityProcessHostClient::OnProcessLaunchFailed(int exit_code) {
OnFailed();
}
bool PdfToEmfUtilityProcessHostClient::OnMessageReceived(
bool PdfConverterUtilityProcessHostClient::OnMessageReceived(
const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(PdfToEmfUtilityProcessHostClient, message)
IPC_BEGIN_MESSAGE_MAP(PdfConverterUtilityProcessHostClient, message)
IPC_MESSAGE_HANDLER(
ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount, OnPageCount)
IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone,
@ -492,59 +576,69 @@ bool PdfToEmfUtilityProcessHostClient::OnMessageReceived(
return handled;
}
bool PdfToEmfUtilityProcessHostClient::Send(IPC::Message* msg) {
if (utility_process_host_)
return utility_process_host_->Send(msg);
delete msg;
return false;
base::string16 PdfConverterUtilityProcessHostClient::GetName() const {
return L"ChromeUtilityProcessPDFConvertor";
}
void PdfToEmfUtilityProcessHostClient::OnFailed() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!start_callback_.is_null())
OnPageCount(0);
while (!get_page_callbacks_.empty())
OnPageDone(false, 0.0f);
utility_process_host_.reset();
void PdfConverterUtilityProcessHostClient::SendGetPageMessage(
int page_number,
IPC::PlatformFileForTransit transit) {
Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage(page_number,
transit));
}
PdfToEmfConverterImpl::PdfToEmfConverterImpl() : weak_ptr_factory_(this) {
void PdfConverterUtilityProcessHostClient::SendStartMessage(
IPC::PlatformFileForTransit transit) {
Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles(transit, settings_));
}
PdfToEmfConverterImpl::~PdfToEmfConverterImpl() {
void PdfConverterUtilityProcessHostClient::SendStopMessage() {
Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop());
}
// Pdf Converter Impl and subclasses
PdfConverterImpl::PdfConverterImpl() : weak_ptr_factory_(this) {}
PdfConverterImpl::~PdfConverterImpl() {
if (utility_client_.get())
utility_client_->Stop();
}
void PdfToEmfConverterImpl::Start(
const scoped_refptr<base::RefCountedMemory>& data,
const PdfRenderSettings& conversion_settings,
bool print_text_with_gdi,
const StartCallback& start_callback) {
DCHECK(!utility_client_.get());
utility_client_ = new PdfToEmfUtilityProcessHostClient(
weak_ptr_factory_.GetWeakPtr(), conversion_settings);
utility_client_->Start(data, print_text_with_gdi, start_callback);
void PdfConverterImpl::Start(
const scoped_refptr<PdfConverterUtilityProcessHostClient>& utility_client,
const scoped_refptr<base::RefCountedMemory>& data,
const StartCallback& start_callback) {
DCHECK(!utility_client_);
utility_client_ = utility_client;
utility_client_->Start(data, start_callback);
}
void PdfToEmfConverterImpl::GetPage(int page_number,
const GetPageCallback& get_page_callback) {
void PdfConverterImpl::GetPage(int page_number,
const GetPageCallback& get_page_callback) {
utility_client_->GetPage(page_number, get_page_callback);
}
void PdfToEmfConverterImpl::RunCallback(const base::Closure& callback) {
void PdfConverterImpl::RunCallback(const base::Closure& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
callback.Run();
}
} // namespace
PdfToEmfConverter::~PdfToEmfConverter() {
}
PdfConverter::~PdfConverter() {}
// static
std::unique_ptr<PdfToEmfConverter> PdfToEmfConverter::CreateDefault() {
return std::unique_ptr<PdfToEmfConverter>(new PdfToEmfConverterImpl());
std::unique_ptr<PdfConverter> PdfConverter::StartPdfConverter(
const scoped_refptr<base::RefCountedMemory>& data,
const PdfRenderSettings& conversion_settings,
const StartCallback& start_callback) {
std::unique_ptr<PdfConverterImpl> converter =
base::MakeUnique<PdfConverterImpl>();
converter->Start(
new PdfConverterUtilityProcessHostClient(converter->GetWeakPtr(),
conversion_settings),
data, start_callback);
return std::move(converter);
}
} // namespace printing

View file

@ -15,24 +15,21 @@ namespace printing {
class MetafilePlayer;
struct PdfRenderSettings;
class PdfToEmfConverter {
class PdfConverter {
public:
typedef base::Callback<void(int page_count)> StartCallback;
typedef base::Callback<void(int page_number,
float scale_factor,
std::unique_ptr<MetafilePlayer> emf)>
GetPageCallback;
virtual ~PdfToEmfConverter();
static std::unique_ptr<PdfToEmfConverter> CreateDefault();
using StartCallback = base::Callback<void(int page_count)>;
using GetPageCallback =
base::Callback<void(int page_number,
float scale_factor,
std::unique_ptr<MetafilePlayer> file)>;
virtual ~PdfConverter();
// Starts conversion of PDF provided as |data|. Calls |start_callback|
// with positive |page_count|. |page_count| is 0 if initialization failed.
virtual void Start(const scoped_refptr<base::RefCountedMemory>& data,
const PdfRenderSettings& conversion_settings,
bool print_text_with_gdi,
const StartCallback& start_callback) = 0;
static std::unique_ptr<PdfConverter> StartPdfConverter(
const scoped_refptr<base::RefCountedMemory>& data,
const PdfRenderSettings& conversion_settings,
const StartCallback& start_callback);
// Requests conversion of the page. |page_number| is 0-base page number in
// PDF provided in Start() call.
@ -41,7 +38,6 @@ class PdfToEmfConverter {
virtual void GetPage(int page_number,
const GetPageCallback& get_page_callback) = 0;
};
} // namespace printing
#endif // CHROME_BROWSER_PRINTING_PDF_TO_EMF_CONVERTER_H_

View file

@ -14,6 +14,7 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/threading/worker_pool.h"
@ -222,27 +223,23 @@ PrintedDocument* PrintJob::document() const {
}
#if defined(OS_WIN)
class PrintJob::PdfToEmfState {
class PrintJob::PdfConversionState {
public:
PdfToEmfState(const gfx::Size& page_size, const gfx::Rect& content_area)
PdfConversionState(gfx::Size page_size, gfx::Rect content_area)
: page_count_(0),
current_page_(0),
pages_in_progress_(0),
page_size_(page_size),
content_area_(content_area),
converter_(PdfToEmfConverter::CreateDefault()) {}
content_area_(content_area) {}
void Start(const scoped_refptr<base::RefCountedMemory>& data,
const PdfRenderSettings& conversion_settings,
bool print_text_with_gdi,
const PdfToEmfConverter::StartCallback& start_callback) {
converter_->Start(data, conversion_settings, print_text_with_gdi,
start_callback);
const PdfConverter::StartCallback& start_callback) {
converter_ = PdfConverter::StartPdfConverter(
data, conversion_settings, start_callback);
}
void GetMorePages(
const PdfToEmfConverter::GetPageCallback& get_page_callback) {
void GetMorePages(const PdfConverter::GetPageCallback& get_page_callback) {
const int kMaxNumberOfTempFilesPerDocument = 3;
while (pages_in_progress_ < kMaxNumberOfTempFilesPerDocument &&
current_page_ < page_count_) {
@ -251,8 +248,7 @@ class PrintJob::PdfToEmfState {
}
}
void OnPageProcessed(
const PdfToEmfConverter::GetPageCallback& get_page_callback) {
void OnPageProcessed(const PdfConverter::GetPageCallback& get_page_callback) {
--pages_in_progress_;
GetMorePages(get_page_callback);
// Release converter if we don't need this any more.
@ -270,7 +266,7 @@ class PrintJob::PdfToEmfState {
int pages_in_progress_;
gfx::Size page_size_;
gfx::Rect content_area_;
std::unique_ptr<PdfToEmfConverter> converter_;
std::unique_ptr<PdfConverter> converter_;
};
void PrintJob::AppendPrintedPage(int page_number) {
@ -282,46 +278,67 @@ void PrintJob::StartPdfToEmfConversion(
const gfx::Size& page_size,
const gfx::Rect& content_area,
bool print_text_with_gdi) {
DCHECK(!pdf_to_emf_state_);
pdf_to_emf_state_ = base::MakeUnique<PdfToEmfState>(page_size, content_area);
DCHECK(!pdf_conversion_state_);
pdf_conversion_state_ =
base::MakeUnique<PdfConversionState>(page_size, content_area);
const int kPrinterDpi = settings().dpi();
pdf_to_emf_state_->Start(
bytes, PdfRenderSettings(content_area, kPrinterDpi, true),
print_text_with_gdi, base::Bind(&PrintJob::OnPdfToEmfStarted, this));
PdfRenderSettings settings(
content_area, gfx::Point(0, 0), kPrinterDpi, /*autorotate=*/true,
print_text_with_gdi ? PdfRenderSettings::Mode::GDI_TEXT
: PdfRenderSettings::Mode::NORMAL);
pdf_conversion_state_->Start(
bytes, settings, base::Bind(&PrintJob::OnPdfConversionStarted, this));
}
void PrintJob::OnPdfToEmfStarted(int page_count) {
void PrintJob::OnPdfConversionStarted(int page_count) {
if (page_count <= 0) {
pdf_to_emf_state_.reset();
pdf_conversion_state_.reset();
Cancel();
return;
}
pdf_to_emf_state_->set_page_count(page_count);
pdf_to_emf_state_->GetMorePages(
base::Bind(&PrintJob::OnPdfToEmfPageConverted, this));
pdf_conversion_state_->set_page_count(page_count);
pdf_conversion_state_->GetMorePages(
base::Bind(&PrintJob::OnPdfPageConverted, this));
}
void PrintJob::OnPdfToEmfPageConverted(int page_number,
float scale_factor,
std::unique_ptr<MetafilePlayer> emf) {
DCHECK(pdf_to_emf_state_);
if (!document_.get() || !emf || page_number < 0 ||
void PrintJob::OnPdfPageConverted(int page_number,
float scale_factor,
std::unique_ptr<MetafilePlayer> metafile) {
DCHECK(pdf_conversion_state_);
if (!document_.get() || !metafile || page_number < 0 ||
static_cast<size_t>(page_number) >= pdf_page_mapping_.size()) {
pdf_to_emf_state_.reset();
pdf_conversion_state_.reset();
Cancel();
return;
}
// Update the rendered document. It will send notifications to the listener.
document_->SetPage(pdf_page_mapping_[page_number], std::move(emf),
scale_factor, pdf_to_emf_state_->page_size(),
pdf_to_emf_state_->content_area());
document_->SetPage(pdf_page_mapping_[page_number], std::move(metafile),
scale_factor, pdf_conversion_state_->page_size(),
pdf_conversion_state_->content_area());
pdf_to_emf_state_->GetMorePages(
base::Bind(&PrintJob::OnPdfToEmfPageConverted, this));
pdf_conversion_state_->GetMorePages(
base::Bind(&PrintJob::OnPdfPageConverted, this));
}
#endif // OS_WIN
void PrintJob::StartPdfToPostScriptConversion(
const scoped_refptr<base::RefCountedMemory>& bytes,
const gfx::Rect& content_area,
const gfx::Point& physical_offsets,
bool ps_level2) {
DCHECK(!pdf_conversion_state_);
pdf_conversion_state_ = base::MakeUnique<PdfConversionState>(
gfx::Size(), gfx::Rect());
const int kPrinterDpi = settings().dpi();
PdfRenderSettings settings(
content_area, physical_offsets, kPrinterDpi, true /* autorotate? */,
ps_level2 ? PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2
: PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3);
pdf_conversion_state_->Start(
bytes, settings, base::Bind(&PrintJob::OnPdfConversionStarted, this));
}
#endif // defined(OS_WIN)
void PrintJob::UpdatePrintedDocument(PrintedDocument* new_document) {
if (document_.get() == new_document)
@ -372,8 +389,10 @@ void PrintJob::OnNotifyPrintJobEvent(const JobEventDetails& event_details) {
}
case JobEventDetails::PAGE_DONE:
#if defined(OS_WIN)
pdf_to_emf_state_->OnPageProcessed(
base::Bind(&PrintJob::OnPdfToEmfPageConverted, this));
if (pdf_conversion_state_) {
pdf_conversion_state_->OnPageProcessed(
base::Bind(&PrintJob::OnPdfPageConverted, this));
}
#endif // defined(OS_WIN)
break;
default: {

View file

@ -100,6 +100,12 @@ class PrintJob : public PrintJobWorkerOwner,
const gfx::Size& page_size,
const gfx::Rect& content_area,
bool print_text_with_gdi);
void StartPdfToPostScriptConversion(
const scoped_refptr<base::RefCountedMemory>& bytes,
const gfx::Rect& content_area,
const gfx::Point& physical_offset,
bool ps_level2);
#endif // defined(OS_WIN)
protected:
@ -126,10 +132,10 @@ class PrintJob : public PrintJobWorkerOwner,
void HoldUntilStopIsCalled();
#if defined(OS_WIN)
void OnPdfToEmfStarted(int page_count);
void OnPdfToEmfPageConverted(int page_number,
float scale_factor,
std::unique_ptr<MetafilePlayer> emf);
void OnPdfConversionStarted(int page_count);
void OnPdfPageConverted(int page_number,
float scale_factor,
std::unique_ptr<MetafilePlayer> emf);
#endif // defined(OS_WIN)
content::NotificationRegistrar registrar_;
@ -157,8 +163,8 @@ class PrintJob : public PrintJobWorkerOwner,
bool is_canceling_;
#if defined(OS_WIN)
class PdfToEmfState;
std::unique_ptr<PdfToEmfState> pdf_to_emf_state_;
class PdfConversionState;
std::unique_ptr<PdfConversionState> pdf_conversion_state_;
std::vector<int> pdf_page_mapping_;
#endif // defined(OS_WIN)

View file

@ -49,25 +49,34 @@
#include <unistd.h>
#include <cstring>
#include <memory>
#include <set>
#include <string>
#include <stddef.h>
#include "atom/common/atom_command_line.h"
#include "base/base_paths.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_descriptor_watcher_posix.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram_macros.h"
#include "base/path_service.h"
#include "base/posix/eintr_wrapper.h"
#include "base/posix/safe_strerror.h"
#include "base/rand_util.h"
#include "base/sequenced_task_runner_helpers.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
@ -78,6 +87,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/network_interfaces.h"
#include "ui/base/l10n/l10n_util.h"
@ -222,9 +232,8 @@ int SetupSocketOnly() {
int sock = socket(PF_UNIX, SOCK_STREAM, 0);
PCHECK(sock >= 0) << "socket() failed";
int rv = base::SetNonBlocking(sock);
DCHECK_EQ(0, rv) << "Failed to make non-blocking socket.";
rv = SetCloseOnExec(sock);
DCHECK(base::SetNonBlocking(sock)) << "Failed to make non-blocking socket.";
int rv = SetCloseOnExec(sock);
DCHECK_EQ(0, rv) << "Failed to set CLOEXEC on socket.";
return sock;
@ -305,7 +314,6 @@ bool ParseLockPath(const base::FilePath& path,
bool DisplayProfileInUseError(const base::FilePath& lock_path,
const std::string& hostname,
int pid) {
// TODO: yolo
return true;
}
@ -455,44 +463,38 @@ bool ReplaceOldSingletonLock(const base::FilePath& symlink_content,
// This class sets up a listener on the singleton socket and handles parsing
// messages that come in on the singleton socket.
class ProcessSingleton::LinuxWatcher
: public base::MessageLoopForIO::Watcher,
public base::MessageLoop::DestructionObserver,
public base::RefCountedThreadSafe<ProcessSingleton::LinuxWatcher,
: public base::RefCountedThreadSafe<ProcessSingleton::LinuxWatcher,
BrowserThread::DeleteOnIOThread> {
public:
// A helper class to read message from an established socket.
class SocketReader : public base::MessageLoopForIO::Watcher {
class SocketReader {
public:
SocketReader(ProcessSingleton::LinuxWatcher* parent,
base::MessageLoop* ui_message_loop,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
int fd)
: parent_(parent),
ui_message_loop_(ui_message_loop),
ui_task_runner_(ui_task_runner),
fd_(fd),
bytes_read_(0) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// Wait for reads.
base::MessageLoopForIO::current()->WatchFileDescriptor(
fd, true, base::MessageLoopForIO::WATCH_READ, &fd_reader_, this);
fd_watch_controller_ = base::FileDescriptorWatcher::WatchReadable(
fd, base::Bind(&SocketReader::OnSocketCanReadWithoutBlocking,
base::Unretained(this)));
// If we haven't completed in a reasonable amount of time, give up.
timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(kTimeoutInSeconds),
this, &SocketReader::CleanupAndDeleteSelf);
}
~SocketReader() override { CloseSocket(fd_); }
// MessageLoopForIO::Watcher impl.
void OnFileCanReadWithoutBlocking(int fd) override;
void OnFileCanWriteWithoutBlocking(int fd) override {
// SocketReader only watches for accept (read) events.
NOTREACHED();
}
~SocketReader() { CloseSocket(fd_); }
// Finish handling the incoming message by optionally sending back an ACK
// message and removing this SocketReader.
void FinishWithACK(const char *message, size_t length);
private:
void OnSocketCanReadWithoutBlocking();
void CleanupAndDeleteSelf() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@ -500,13 +502,15 @@ class ProcessSingleton::LinuxWatcher
// We're deleted beyond this point.
}
base::MessageLoopForIO::FileDescriptorWatcher fd_reader_;
// Controls watching |fd_|.
std::unique_ptr<base::FileDescriptorWatcher::Controller>
fd_watch_controller_;
// The ProcessSingleton::LinuxWatcher that owns us.
ProcessSingleton::LinuxWatcher* const parent_;
// A reference to the UI message loop.
base::MessageLoop* const ui_message_loop_;
// A reference to the UI task runner.
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
// The file descriptor we're reading.
const int fd_;
@ -525,9 +529,7 @@ class ProcessSingleton::LinuxWatcher
// We expect to only be constructed on the UI thread.
explicit LinuxWatcher(ProcessSingleton* parent)
: ui_message_loop_(base::MessageLoop::current()),
parent_(parent) {
}
: ui_task_runner_(base::ThreadTaskRunnerHandle::Get()), parent_(parent) {}
// Start listening for connections on the socket. This method should be
// called from the IO thread.
@ -540,79 +542,63 @@ class ProcessSingleton::LinuxWatcher
const std::vector<std::string>& argv,
SocketReader* reader);
// MessageLoopForIO::Watcher impl. These run on the IO thread.
void OnFileCanReadWithoutBlocking(int fd) override;
void OnFileCanWriteWithoutBlocking(int fd) override {
// ProcessSingleton only watches for accept (read) events.
NOTREACHED();
}
// MessageLoop::DestructionObserver
void WillDestroyCurrentMessageLoop() override {
fd_watcher_.StopWatchingFileDescriptor();
}
private:
friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
friend class base::DeleteHelper<ProcessSingleton::LinuxWatcher>;
~LinuxWatcher() override {
~LinuxWatcher() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
STLDeleteElements(&readers_);
base::MessageLoopForIO* ml = base::MessageLoopForIO::current();
ml->RemoveDestructionObserver(this);
}
void OnSocketCanReadWithoutBlocking(int socket);
// Removes and deletes the SocketReader.
void RemoveSocketReader(SocketReader* reader);
base::MessageLoopForIO::FileDescriptorWatcher fd_watcher_;
std::unique_ptr<base::FileDescriptorWatcher::Controller> socket_watcher_;
// A reference to the UI message loop (i.e., the message loop we were
// constructed on).
base::MessageLoop* ui_message_loop_;
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
// The ProcessSingleton that owns us.
ProcessSingleton* const parent_;
std::set<SocketReader*> readers_;
std::set<std::unique_ptr<SocketReader>> readers_;
DISALLOW_COPY_AND_ASSIGN(LinuxWatcher);
};
void ProcessSingleton::LinuxWatcher::OnFileCanReadWithoutBlocking(int fd) {
void ProcessSingleton::LinuxWatcher::OnSocketCanReadWithoutBlocking(
int socket) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// Accepting incoming client.
sockaddr_un from;
socklen_t from_len = sizeof(from);
int connection_socket = HANDLE_EINTR(accept(
fd, reinterpret_cast<sockaddr*>(&from), &from_len));
int connection_socket = HANDLE_EINTR(
accept(socket, reinterpret_cast<sockaddr*>(&from), &from_len));
if (-1 == connection_socket) {
PLOG(ERROR) << "accept() failed";
return;
}
int rv = base::SetNonBlocking(connection_socket);
DCHECK_EQ(0, rv) << "Failed to make non-blocking socket.";
SocketReader* reader = new SocketReader(this,
ui_message_loop_,
connection_socket);
readers_.insert(reader);
DCHECK(base::SetNonBlocking(connection_socket))
<< "Failed to make non-blocking socket.";
readers_.insert(
base::MakeUnique<SocketReader>(this, ui_task_runner_, connection_socket));
}
void ProcessSingleton::LinuxWatcher::StartListening(int socket) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// Watch for client connections on this socket.
base::MessageLoopForIO* ml = base::MessageLoopForIO::current();
ml->AddDestructionObserver(this);
ml->WatchFileDescriptor(socket, true, base::MessageLoopForIO::WATCH_READ,
&fd_watcher_, this);
socket_watcher_ = base::FileDescriptorWatcher::WatchReadable(
socket, base::Bind(&LinuxWatcher::OnSocketCanReadWithoutBlocking,
base::Unretained(this), socket));
}
void ProcessSingleton::LinuxWatcher::HandleMessage(
const std::string& current_dir, const std::vector<std::string>& argv,
SocketReader* reader) {
DCHECK(ui_message_loop_ == base::MessageLoop::current());
DCHECK(ui_task_runner_->BelongsToCurrentThread());
DCHECK(reader);
if (parent_->notification_callback_.Run(argv,
@ -632,25 +618,27 @@ void ProcessSingleton::LinuxWatcher::HandleMessage(
void ProcessSingleton::LinuxWatcher::RemoveSocketReader(SocketReader* reader) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(reader);
readers_.erase(reader);
delete reader;
auto it = std::find_if(readers_.begin(), readers_.end(),
[reader](const std::unique_ptr<SocketReader>& ptr) {
return ptr.get() == reader;
});
readers_.erase(it);
}
///////////////////////////////////////////////////////////////////////////////
// ProcessSingleton::LinuxWatcher::SocketReader
//
void ProcessSingleton::LinuxWatcher::SocketReader::OnFileCanReadWithoutBlocking(
int fd) {
void ProcessSingleton::LinuxWatcher::SocketReader::
OnSocketCanReadWithoutBlocking() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK_EQ(fd, fd_);
while (bytes_read_ < sizeof(buf_)) {
ssize_t rv = HANDLE_EINTR(
read(fd, buf_ + bytes_read_, sizeof(buf_) - bytes_read_));
ssize_t rv =
HANDLE_EINTR(read(fd_, buf_ + bytes_read_, sizeof(buf_) - bytes_read_));
if (rv < 0) {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
PLOG(ERROR) << "read() failed";
CloseSocket(fd);
CloseSocket(fd_);
return;
} else {
// It would block, so we just return and continue to watch for the next
@ -696,10 +684,10 @@ void ProcessSingleton::LinuxWatcher::SocketReader::OnFileCanReadWithoutBlocking(
tokens.erase(tokens.begin());
// Return to the UI thread to handle opening a new browser tab.
ui_message_loop_->task_runner()->PostTask(
ui_task_runner_->PostTask(
FROM_HERE, base::Bind(&ProcessSingleton::LinuxWatcher::HandleMessage,
parent_, current_dir, tokens, this));
fd_reader_.StopWatchingFileDescriptor();
fd_watch_controller_.reset();
// LinuxWatcher::HandleMessage() is in charge of destroying this SocketReader
// object by invoking SocketReader::FinishWithACK().
@ -731,7 +719,8 @@ ProcessSingleton::ProcessSingleton(
const base::FilePath& user_data_dir,
const NotificationCallback& notification_callback)
: notification_callback_(notification_callback),
current_pid_(base::GetCurrentProcId()) {
current_pid_(base::GetCurrentProcId()),
watcher_(new LinuxWatcher(this)) {
// The user_data_dir may have not been created yet.
base::CreateDirectoryAndGetError(user_data_dir, nullptr);
@ -897,12 +886,26 @@ ProcessSingleton::NotifyOtherProcessWithTimeoutOrCreate(
const base::CommandLine& command_line,
int retry_attempts,
const base::TimeDelta& timeout) {
const base::TimeTicks begin_ticks = base::TimeTicks::Now();
NotifyResult result = NotifyOtherProcessWithTimeout(
command_line, retry_attempts, timeout, true);
if (result != PROCESS_NONE)
if (result != PROCESS_NONE) {
if (result == PROCESS_NOTIFIED) {
UMA_HISTOGRAM_MEDIUM_TIMES("Chrome.ProcessSingleton.TimeToNotify",
base::TimeTicks::Now() - begin_ticks);
} else {
UMA_HISTOGRAM_MEDIUM_TIMES("Chrome.ProcessSingleton.TimeToFailure",
base::TimeTicks::Now() - begin_ticks);
}
return result;
if (Create())
}
if (Create()) {
UMA_HISTOGRAM_MEDIUM_TIMES("Chrome.ProcessSingleton.TimeToCreate",
base::TimeTicks::Now() - begin_ticks);
return PROCESS_NONE;
}
// If the Create() failed, try again to notify. (It could be that another
// instance was starting at the same time and managed to grab the lock before
// we did.)
@ -910,6 +913,15 @@ ProcessSingleton::NotifyOtherProcessWithTimeoutOrCreate(
// aren't going to try to take over the lock ourselves.
result = NotifyOtherProcessWithTimeout(
command_line, retry_attempts, timeout, false);
if (result == PROCESS_NOTIFIED) {
UMA_HISTOGRAM_MEDIUM_TIMES("Chrome.ProcessSingleton.TimeToNotify",
base::TimeTicks::Now() - begin_ticks);
} else {
UMA_HISTOGRAM_MEDIUM_TIMES("Chrome.ProcessSingleton.TimeToFailure",
base::TimeTicks::Now() - begin_ticks);
}
if (result != PROCESS_NONE)
return result;
@ -1019,15 +1031,13 @@ bool ProcessSingleton::Create() {
if (listen(sock, 5) < 0)
NOTREACHED() << "listen failed: " << base::safe_strerror(errno);
// In Electron the ProcessSingleton is created earlier than the IO
// thread gets created, so we have to postpone the call until message
// loop is up an running.
scoped_refptr<base::SingleThreadTaskRunner> task_runner =
base::ThreadTaskRunnerHandle::Get();
task_runner->PostTask(
DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::IO));
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
base::Bind(&ProcessSingleton::StartListening,
base::Unretained(this), sock));
base::Bind(&ProcessSingleton::LinuxWatcher::StartListening,
watcher_,
sock));
return true;
}
@ -1038,17 +1048,6 @@ void ProcessSingleton::Cleanup() {
UnlinkPath(lock_path_);
}
void ProcessSingleton::StartListening(int sock) {
watcher_ = new LinuxWatcher(this);
DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::IO));
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
base::Bind(&ProcessSingleton::LinuxWatcher::StartListening,
watcher_.get(),
sock));
}
bool ProcessSingleton::IsSameChromeInstance(pid_t pid) {
pid_t cur_pid = current_pid_;
while (pid != cur_pid) {

View file

@ -0,0 +1,111 @@
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Multiply-included message file, so no include guard.
#include <string>
#include <vector>
#include "base/strings/string16.h"
#include "build/build_config.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_param_traits.h"
#include "ipc/ipc_platform_file.h"
#include "printing/backend/print_backend.h"
#include "printing/features/features.h"
#include "printing/page_range.h"
#include "printing/pdf_render_settings.h"
#include "printing/pwg_raster_settings.h"
#if defined(OS_WIN)
#include <windows.h>
#endif
#define IPC_MESSAGE_START ChromeUtilityPrintingMsgStart
IPC_ENUM_TRAITS_MAX_VALUE(printing::PdfRenderSettings::Mode,
printing::PdfRenderSettings::Mode::LAST)
IPC_STRUCT_TRAITS_BEGIN(printing::PdfRenderSettings)
IPC_STRUCT_TRAITS_MEMBER(area)
IPC_STRUCT_TRAITS_MEMBER(offsets)
IPC_STRUCT_TRAITS_MEMBER(dpi)
IPC_STRUCT_TRAITS_MEMBER(autorotate)
IPC_STRUCT_TRAITS_MEMBER(mode)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(printing::PrinterCapsAndDefaults)
IPC_STRUCT_TRAITS_MEMBER(printer_capabilities)
IPC_STRUCT_TRAITS_MEMBER(caps_mime_type)
IPC_STRUCT_TRAITS_MEMBER(printer_defaults)
IPC_STRUCT_TRAITS_MEMBER(defaults_mime_type)
IPC_STRUCT_TRAITS_END()
IPC_ENUM_TRAITS_MAX_VALUE(printing::ColorModel, printing::PROCESSCOLORMODEL_RGB)
IPC_STRUCT_TRAITS_BEGIN(printing::PrinterSemanticCapsAndDefaults::Paper)
IPC_STRUCT_TRAITS_MEMBER(display_name)
IPC_STRUCT_TRAITS_MEMBER(vendor_id)
IPC_STRUCT_TRAITS_MEMBER(size_um)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(printing::PrinterSemanticCapsAndDefaults)
IPC_STRUCT_TRAITS_MEMBER(collate_capable)
IPC_STRUCT_TRAITS_MEMBER(collate_default)
IPC_STRUCT_TRAITS_MEMBER(copies_capable)
IPC_STRUCT_TRAITS_MEMBER(duplex_capable)
IPC_STRUCT_TRAITS_MEMBER(duplex_default)
IPC_STRUCT_TRAITS_MEMBER(color_changeable)
IPC_STRUCT_TRAITS_MEMBER(color_default)
IPC_STRUCT_TRAITS_MEMBER(color_model)
IPC_STRUCT_TRAITS_MEMBER(bw_model)
IPC_STRUCT_TRAITS_MEMBER(papers)
IPC_STRUCT_TRAITS_MEMBER(default_paper)
IPC_STRUCT_TRAITS_MEMBER(dpis)
IPC_STRUCT_TRAITS_MEMBER(default_dpi)
IPC_STRUCT_TRAITS_END()
IPC_ENUM_TRAITS_MAX_VALUE(printing::PwgRasterTransformType,
printing::TRANSFORM_TYPE_LAST)
IPC_STRUCT_TRAITS_BEGIN(printing::PwgRasterSettings)
IPC_STRUCT_TRAITS_MEMBER(odd_page_transform)
IPC_STRUCT_TRAITS_MEMBER(rotate_all_pages)
IPC_STRUCT_TRAITS_MEMBER(reverse_page_order)
IPC_STRUCT_TRAITS_END()
#if defined(OS_WIN)
// Reply when the utility process loaded PDF. |page_count| is 0, if loading
// failed.
IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount,
int /* page_count */)
// Reply when the utility process rendered the PDF page.
IPC_MESSAGE_CONTROL2(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone,
bool /* success */,
float /* scale_factor */)
// Request that the given font characters be loaded by the browser so it's
// cached by the OS. Please see
// PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters for details.
IPC_SYNC_MESSAGE_CONTROL2_0(ChromeUtilityHostMsg_PreCacheFontCharacters,
LOGFONT /* font_data */,
base::string16 /* characters */)
// Tell the utility process to start rendering the given PDF into a metafile.
// Utility process would be alive until
// ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop message.
IPC_MESSAGE_CONTROL2(ChromeUtilityMsg_RenderPDFPagesToMetafiles,
IPC::PlatformFileForTransit /* input_file */,
printing::PdfRenderSettings /* settings */)
// Requests conversion of the next page.
IPC_MESSAGE_CONTROL2(ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage,
int /* page_number */,
IPC::PlatformFileForTransit /* output_file */)
// Requests utility process to stop conversion and exit.
IPC_MESSAGE_CONTROL0(ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop)
#endif // OS_WIN

View file

@ -75,6 +75,9 @@ struct PrintMsg_PrintPages_Params {
IPC_ENUM_TRAITS_MAX_VALUE(printing::MarginType,
printing::MARGIN_TYPE_LAST)
IPC_ENUM_TRAITS_MIN_MAX_VALUE(printing::DuplexMode,
printing::UNKNOWN_DUPLEX_MODE,
printing::SHORT_EDGE)
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebPrintScalingOption,
blink::WebPrintScalingOptionLast)
@ -317,39 +320,3 @@ IPC_MESSAGE_ROUTED1(PrintHostMsg_MetafileReadyForPrinting,
IPC_MESSAGE_ROUTED2(PrintHostMsg_PrintPreviewFailed,
int /* document cookie */,
int /* request_id */);
#if defined(OS_WIN)
// Tell the utility process to start rendering the given PDF into a metafile.
// Utility process would be alive until
// ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop message.
IPC_MESSAGE_CONTROL3(ChromeUtilityMsg_RenderPDFPagesToMetafiles,
IPC::PlatformFileForTransit /* input_file */,
printing::PdfRenderSettings /* settings */,
bool /* print_text_with_gdi */)
// Requests conversion of the next page.
IPC_MESSAGE_CONTROL2(ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage,
int /* page_number */,
IPC::PlatformFileForTransit /* output_file */)
// Requests utility process to stop conversion and exit.
IPC_MESSAGE_CONTROL0(ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop)
// Reply when the utility process loaded PDF. |page_count| is 0, if loading
// failed.
IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount,
int /* page_count */)
// Reply when the utility process rendered the PDF page.
IPC_MESSAGE_CONTROL2(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone,
bool /* success */,
float /* scale_factor */)
// Request that the given font characters be loaded by the browser so it's
// cached by the OS. Please see
// PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters for details.
IPC_SYNC_MESSAGE_CONTROL2_0(ChromeUtilityHostMsg_PreCacheFontCharacters,
LOGFONT /* font_data */,
base::string16 /* characters */)
#endif

View file

@ -66,11 +66,11 @@ class ExternalClearKeyProperties : public KeySystemProperties {
return true;
case media::EmeInitDataType::CENC:
#if defined(USE_PROPRIETARY_CODECS)
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
return true;
#else
return false;
#endif // defined(USE_PROPRIETARY_CODECS)
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
case media::EmeInitDataType::UNKNOWN:
return false;
@ -80,7 +80,7 @@ class ExternalClearKeyProperties : public KeySystemProperties {
}
SupportedCodecs GetSupportedCodecs() const override {
#if defined(USE_PROPRIETARY_CODECS)
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
return media::EME_CODEC_MP4_ALL | media::EME_CODEC_WEBM_ALL;
#else
return media::EME_CODEC_WEBM_ALL;
@ -224,21 +224,21 @@ static void AddPepperBasedWidevine(
// as those may offer a higher level of protection.
supported_codecs |= media::EME_CODEC_WEBM_OPUS;
supported_codecs |= media::EME_CODEC_WEBM_VORBIS;
#if defined(USE_PROPRIETARY_CODECS)
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
supported_codecs |= media::EME_CODEC_MP4_AAC;
#endif // defined(USE_PROPRIETARY_CODECS)
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
for (size_t i = 0; i < codecs.size(); ++i) {
if (codecs[i] == kCdmSupportedCodecVp8)
supported_codecs |= media::EME_CODEC_WEBM_VP8;
if (codecs[i] == kCdmSupportedCodecVp9)
supported_codecs |= media::EME_CODEC_WEBM_VP9;
#if defined(USE_PROPRIETARY_CODECS)
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
if (codecs[i] == kCdmSupportedCodecAvc1)
supported_codecs |= media::EME_CODEC_MP4_AVC1;
if (codecs[i] == kCdmSupportedCodecVp9)
supported_codecs |= media::EME_CODEC_MP4_VP9;
#endif // defined(USE_PROPRIETARY_CODECS)
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
}
using Robustness = cdm::WidevineKeySystemProperties::Robustness;

View file

@ -15,7 +15,8 @@
#include "ppapi/proxy/serialized_structs.h"
#if defined(OS_LINUX) || defined(OS_OPENBSD)
#include "content/public/common/child_process_sandbox_support_linux.h"
#include "content/public/child/child_process_sandbox_support_linux.h"
#include "content/public/common/common_sandbox_support_linux.h"
#elif defined(OS_WIN)
#include "third_party/skia/include/ports/SkFontMgr.h"
#endif

View file

@ -8,7 +8,8 @@
#include <vector>
#include "base/lazy_instance.h"
#include "base/metrics/histogram.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_util.h"
#include "content/public/renderer/pepper_plugin_instance.h"
#include "content/public/renderer/render_thread.h"

View file

@ -12,7 +12,7 @@
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/metrics/histogram_macros.h"
#include "base/process/process_handle.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
@ -32,6 +32,7 @@
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebElement.h"
#include "third_party/WebKit/public/web/WebFrameClient.h"
#include "third_party/WebKit/public/web/WebFrameWidget.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebPlugin.h"
#include "third_party/WebKit/public/web/WebPluginDocument.h"
@ -484,12 +485,9 @@ void PrepareFrameAndViewForPrint::ResizeForPrinting() {
// Backup size and offset if it's a local frame.
blink::WebView* web_view = frame_.view();
// Backup size and offset.
if (blink::WebFrame* web_frame = web_view->mainFrame())
prev_scroll_offset_ = web_frame->scrollOffset();
if (blink::WebFrame* web_frame = web_view->mainFrame()) {
if (web_frame->isWebLocalFrame())
prev_scroll_offset_ = web_frame->scrollOffset();
prev_scroll_offset_ = web_frame->getScrollOffset();
}
prev_view_size_ = web_view->size();
@ -535,8 +533,10 @@ void PrepareFrameAndViewForPrint::CopySelection(
blink::WebView::create(this, blink::WebPageVisibilityStateVisible);
owns_web_view_ = true;
content::RenderView::ApplyWebPreferences(prefs, web_view);
web_view->setMainFrame(
blink::WebLocalFrame::create(blink::WebTreeScopeType::Document, this));
blink::WebLocalFrame* main_frame = blink::WebLocalFrame::create(
blink::WebTreeScopeType::Document, this, nullptr, nullptr);
web_view->setMainFrame(main_frame);
blink::WebFrameWidget::create(this, web_view, main_frame);
frame_.Reset(web_view->mainFrame()->toWebLocalFrame());
node_to_print_.reset();
@ -565,7 +565,8 @@ blink::WebLocalFrame* PrepareFrameAndViewForPrint::createChildFrame(
const blink::WebString& unique_name,
blink::WebSandboxFlags sandbox_flags,
const blink::WebFrameOwnerProperties& frame_owner_properties) {
blink::WebLocalFrame* frame = blink::WebLocalFrame::create(scope, this);
blink::WebLocalFrame* frame = blink::WebLocalFrame::create(
scope, this, nullptr, nullptr);
parent->appendChild(frame);
return frame;
}

View file

@ -126,12 +126,12 @@ void PrintWebViewHelper::PrintPageInternal(
&content_area);
gfx::Rect canvas_area = content_area;
SkCanvas* canvas = metafile->GetVectorCanvasForNewPage(
page_size, canvas_area, scale_factor);
cc::PaintCanvas* canvas =
metafile->GetVectorCanvasForNewPage(page_size, canvas_area, scale_factor);
if (!canvas)
return;
MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile);
MetafileSkiaWrapper::SetMetafileOnCanvas(canvas, metafile);
RenderPageContent(frame, params.page_number, canvas_area, content_area,
scale_factor, canvas);

View file

@ -14,7 +14,6 @@
#include "printing/page_size_margins.h"
#include "third_party/WebKit/public/platform/WebCanvas.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/skia/include/core/SkCanvas.h"
namespace printing {
@ -112,13 +111,13 @@ void PrintWebViewHelper::RenderPage(const PrintMsg_Print_Params& params,
gfx::Rect canvas_area = content_area;
{
SkCanvas* canvas = metafile->GetVectorCanvasForNewPage(
cc::PaintCanvas* canvas = metafile->GetVectorCanvasForNewPage(
*page_size, canvas_area, scale_factor);
if (!canvas)
return;
MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile);
skia::SetIsPreviewMetafile(*canvas, is_preview);
MetafileSkiaWrapper::SetMetafileOnCanvas(canvas, metafile);
cc::SetIsPreviewMetafile(canvas, is_preview);
RenderPageContent(frame, page_number, canvas_area, content_area,
scale_factor, static_cast<blink::WebCanvas*>(canvas));
}

View file

@ -14,7 +14,6 @@
#include "printing/page_size_margins.h"
#include "printing/pdf_metafile_skia.h"
#include "printing/units.h"
#include "skia/ext/platform_device.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
@ -161,12 +160,12 @@ void PrintWebViewHelper::PrintPageInternal(
frame->getPrintPageShrink(params.page_number);
float scale_factor = css_scale_factor * webkit_page_shrink_factor;
SkCanvas* canvas = metafile->GetVectorCanvasForNewPage(
page_size, canvas_area, scale_factor);
cc::PaintCanvas* canvas =
metafile->GetVectorCanvasForNewPage(page_size, canvas_area, scale_factor);
if (!canvas)
return;
MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile);
MetafileSkiaWrapper::SetMetafileOnCanvas(canvas, metafile);
#if 0
if (params.params.display_header_footer) {

View file

@ -8,6 +8,7 @@
#include "base/lazy_instance.h"
#include "base/path_service.h"
#include "base/scoped_native_library.h"
#include "chrome/common/chrome_utility_printing_messages.h"
#include "chrome/common/print_messages.h"
#include "content/public/utility/utility_thread.h"
#include "pdf/pdf.h"
@ -59,13 +60,25 @@ bool PrintingHandlerWin::OnMessageReceived(const IPC::Message& message) {
void PrintingHandlerWin::OnRenderPDFPagesToMetafile(
IPC::PlatformFileForTransit pdf_transit,
const PdfRenderSettings& settings,
bool print_text_with_gdi) {
const PdfRenderSettings& settings) {
pdf_rendering_settings_ = settings;
chrome_pdf::SetPDFUseGDIPrinting(print_text_with_gdi);
chrome_pdf::SetPDFUseGDIPrinting(pdf_rendering_settings_.mode ==
PdfRenderSettings::Mode::GDI_TEXT);
int postscript_level;
switch (pdf_rendering_settings_.mode) {
case PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2:
postscript_level = 2;
break;
case PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3:
postscript_level = 3;
break;
default:
postscript_level = 0; // Not using postscript.
}
chrome_pdf::SetPDFPostscriptPrintingLevel(postscript_level);
base::File pdf_file = IPC::PlatformFileForTransitToFile(pdf_transit);
int page_count = LoadPDF(std::move(pdf_file));
//int page_count = 1;
Send(
new ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount(page_count));
}
@ -75,8 +88,12 @@ void PrintingHandlerWin::OnRenderPDFPagesToMetafileGetPage(
IPC::PlatformFileForTransit output_file) {
base::File emf_file = IPC::PlatformFileForTransitToFile(output_file);
float scale_factor = 1.0f;
bool success =
RenderPdfPageToMetafile(page_number, std::move(emf_file), &scale_factor);
bool postscript = pdf_rendering_settings_.mode ==
PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2 ||
pdf_rendering_settings_.mode ==
PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3;
bool success = RenderPdfPageToMetafile(page_number, std::move(emf_file),
&scale_factor, postscript);
Send(new ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone(
success, scale_factor));
}
@ -105,7 +122,8 @@ int PrintingHandlerWin::LoadPDF(base::File pdf_file) {
bool PrintingHandlerWin::RenderPdfPageToMetafile(int page_number,
base::File output_file,
float* scale_factor) {
float* scale_factor,
bool postscript) {
Emf metafile;
metafile.Init();
@ -116,18 +134,30 @@ bool PrintingHandlerWin::RenderPdfPageToMetafile(int page_number,
// original coordinates and we'll be able to print in full resolution.
// Before playback we'll need to counter the scaling up that will happen
// in the service (print_system_win.cc).
*scale_factor = gfx::CalculatePageScale(
metafile.context(), pdf_rendering_settings_.area.right(),
pdf_rendering_settings_.area.bottom());
gfx::ScaleDC(metafile.context(), *scale_factor);
//
// The postscript driver does not use the metafile size since it outputs
// postscript rather than a metafile. Instead it uses the printable area
// sent to RenderPDFPageToDC to determine the area to render. Therefore,
// don't scale the DC to match the metafile, and send the printer physical
// offsets to the driver.
if (!postscript) {
*scale_factor = gfx::CalculatePageScale(
metafile.context(), pdf_rendering_settings_.area.right(),
pdf_rendering_settings_.area.bottom());
gfx::ScaleDC(metafile.context(), *scale_factor);
}
// The underlying metafile is of type Emf and ignores the arguments passed
// to StartPage.
metafile.StartPage(gfx::Size(), gfx::Rect(), 1);
int offset_x = postscript ? pdf_rendering_settings_.offsets.x() : 0;
int offset_y = postscript ? pdf_rendering_settings_.offsets.y() : 0;
if (!chrome_pdf::RenderPDFPageToDC(
&pdf_data_.front(), pdf_data_.size(), page_number, metafile.context(),
pdf_rendering_settings_.dpi, pdf_rendering_settings_.area.x(),
pdf_rendering_settings_.area.y(),
pdf_rendering_settings_.dpi,
pdf_rendering_settings_.area.x() - offset_x,
pdf_rendering_settings_.area.y() - offset_y,
pdf_rendering_settings_.area.width(),
pdf_rendering_settings_.area.height(), true, false, true, true,
pdf_rendering_settings_.autorotate)) {
@ -138,4 +168,4 @@ bool PrintingHandlerWin::RenderPdfPageToMetafile(int page_number,
return metafile.SaveTo(&output_file);
}
} // printing
} // namespace printing

View file

@ -29,8 +29,7 @@ class PrintingHandlerWin : public UtilityMessageHandler {
private:
// IPC message handlers.
void OnRenderPDFPagesToMetafile(IPC::PlatformFileForTransit pdf_transit,
const PdfRenderSettings& settings,
bool print_text_with_gdi);
const PdfRenderSettings& settings);
void OnRenderPDFPagesToMetafileGetPage(
int page_number,
IPC::PlatformFileForTransit output_file);
@ -39,7 +38,8 @@ class PrintingHandlerWin : public UtilityMessageHandler {
int LoadPDF(base::File pdf_file);
bool RenderPdfPageToMetafile(int page_number,
base::File output_file,
float* scale_factor);
float* scale_factor,
bool postscript);
std::vector<char> pdf_data_;
PdfRenderSettings pdf_rendering_settings_;

View file

@ -47,7 +47,7 @@ int32_t PepperPDFHost::OnHostMsgDidStartLoading(
if (!render_frame)
return PP_ERROR_FAILED;
render_frame->DidStartLoading();
render_frame->PluginDidStartLoading();
return PP_OK;
}
@ -57,7 +57,7 @@ int32_t PepperPDFHost::OnHostMsgDidStopLoading(
if (!render_frame)
return PP_ERROR_FAILED;
render_frame->DidStopLoading();
render_frame->PluginDidStopLoading();
return PP_OK;
}

View file

@ -1,333 +0,0 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/test/embedded_test_server/stream_listen_socket.h"
#include <memory>
#if defined(OS_WIN)
// winsock2.h must be included first in order to ensure it is included before
// windows.h.
#include <winsock2.h>
#elif defined(OS_POSIX)
#include <arpa/inet.h>
#include <errno.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include "net/base/net_errors.h"
#endif
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/posix/eintr_wrapper.h"
#include "base/sys_byteorder.h"
#include "base/threading/platform_thread.h"
#include "build/build_config.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/base/network_interfaces.h"
#include "net/base/sockaddr_storage.h"
#include "net/socket/socket_descriptor.h"
using std::string;
#if defined(OS_WIN)
typedef int socklen_t;
#endif // defined(OS_WIN)
namespace net {
namespace test_server {
namespace {
const int kReadBufSize = 4096;
} // namespace
#if defined(OS_WIN)
const int StreamListenSocket::kSocketError = SOCKET_ERROR;
#elif defined(OS_POSIX)
const int StreamListenSocket::kSocketError = -1;
#endif
StreamListenSocket::StreamListenSocket(SocketDescriptor s,
StreamListenSocket::Delegate* del)
: socket_delegate_(del),
socket_(s),
reads_paused_(false),
has_pending_reads_(false) {
#if defined(OS_WIN)
socket_event_ = WSACreateEvent();
// TODO(ibrar): error handling in case of socket_event_ == WSA_INVALID_EVENT.
WatchSocket(NOT_WAITING);
#elif defined(OS_POSIX)
wait_state_ = NOT_WAITING;
#endif
}
StreamListenSocket::~StreamListenSocket() {
CloseSocket();
#if defined(OS_WIN)
if (socket_event_) {
WSACloseEvent(socket_event_);
socket_event_ = WSA_INVALID_EVENT;
}
#endif
}
void StreamListenSocket::Send(const char* bytes,
int len,
bool append_linefeed) {
SendInternal(bytes, len);
if (append_linefeed)
SendInternal("\r\n", 2);
}
void StreamListenSocket::Send(const string& str, bool append_linefeed) {
Send(str.data(), static_cast<int>(str.length()), append_linefeed);
}
int StreamListenSocket::GetLocalAddress(IPEndPoint* address) const {
SockaddrStorage storage;
if (getsockname(socket_, storage.addr, &storage.addr_len)) {
#if defined(OS_WIN)
int err = WSAGetLastError();
#else
int err = errno;
#endif
return MapSystemError(err);
}
if (!address->FromSockAddr(storage.addr, storage.addr_len))
return ERR_ADDRESS_INVALID;
return OK;
}
int StreamListenSocket::GetPeerAddress(IPEndPoint* address) const {
SockaddrStorage storage;
if (getpeername(socket_, storage.addr, &storage.addr_len)) {
#if defined(OS_WIN)
int err = WSAGetLastError();
#else
int err = errno;
#endif
return MapSystemError(err);
}
if (!address->FromSockAddr(storage.addr, storage.addr_len))
return ERR_ADDRESS_INVALID;
return OK;
}
SocketDescriptor StreamListenSocket::AcceptSocket() {
SocketDescriptor conn = HANDLE_EINTR(accept(socket_, NULL, NULL));
if (conn == kInvalidSocket)
LOG(ERROR) << "Error accepting connection.";
else
base::SetNonBlocking(conn);
return conn;
}
void StreamListenSocket::SendInternal(const char* bytes, int len) {
char* send_buf = const_cast<char*>(bytes);
int len_left = len;
while (true) {
int sent = HANDLE_EINTR(send(socket_, send_buf, len_left, 0));
if (sent == len_left) { // A shortcut to avoid extraneous checks.
break;
}
if (sent == kSocketError) {
#if defined(OS_WIN)
if (WSAGetLastError() != WSAEWOULDBLOCK) {
LOG(ERROR) << "send failed: WSAGetLastError()==" << WSAGetLastError();
#elif defined(OS_POSIX)
if (errno != EWOULDBLOCK && errno != EAGAIN) {
LOG(ERROR) << "send failed: errno==" << errno;
#endif
break;
}
// Otherwise we would block, and now we have to wait for a retry.
// Fall through to PlatformThread::YieldCurrentThread()
} else {
// sent != len_left according to the shortcut above.
// Shift the buffer start and send the remainder after a short while.
send_buf += sent;
len_left -= sent;
}
base::PlatformThread::YieldCurrentThread();
}
}
void StreamListenSocket::Listen() {
int backlog = 10; // TODO(erikkay): maybe don't allow any backlog?
if (listen(socket_, backlog) == -1) {
// TODO(erikkay): error handling.
LOG(ERROR) << "Could not listen on socket.";
return;
}
#if defined(OS_POSIX)
WatchSocket(WAITING_ACCEPT);
#endif
}
void StreamListenSocket::Read() {
char buf[kReadBufSize + 1]; // +1 for null termination.
int len;
do {
len = HANDLE_EINTR(recv(socket_, buf, kReadBufSize, 0));
if (len == kSocketError) {
#if defined(OS_WIN)
int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK) {
#elif defined(OS_POSIX)
if (errno == EWOULDBLOCK || errno == EAGAIN) {
#endif
break;
} else {
// TODO(ibrar): some error handling required here.
break;
}
} else if (len == 0) {
#if defined(OS_POSIX)
// In Windows, Close() is called by OnObjectSignaled. In POSIX, we need
// to call it here.
Close();
#endif
} else {
// TODO(ibrar): maybe change DidRead to take a length instead.
DCHECK_GT(len, 0);
DCHECK_LE(len, kReadBufSize);
buf[len] = 0; // Already create a buffer with +1 length.
socket_delegate_->DidRead(this, buf, len);
}
} while (len == kReadBufSize);
}
void StreamListenSocket::Close() {
#if defined(OS_POSIX)
if (wait_state_ == NOT_WAITING)
return;
wait_state_ = NOT_WAITING;
#endif
UnwatchSocket();
socket_delegate_->DidClose(this);
}
void StreamListenSocket::CloseSocket() {
if (socket_ != kInvalidSocket) {
UnwatchSocket();
#if defined(OS_WIN)
closesocket(socket_);
#elif defined(OS_POSIX)
close(socket_);
#endif
}
}
void StreamListenSocket::WatchSocket(WaitState state) {
#if defined(OS_WIN)
WSAEventSelect(socket_, socket_event_, FD_ACCEPT | FD_CLOSE | FD_READ);
watcher_.StartWatchingOnce(socket_event_, this);
#elif defined(OS_POSIX)
// Implicitly calls StartWatchingFileDescriptor().
base::MessageLoopForIO::current()->WatchFileDescriptor(
socket_, true, base::MessageLoopForIO::WATCH_READ, &watcher_, this);
wait_state_ = state;
#endif
}
void StreamListenSocket::UnwatchSocket() {
#if defined(OS_WIN)
watcher_.StopWatching();
#elif defined(OS_POSIX)
watcher_.StopWatchingFileDescriptor();
#endif
}
// TODO(ibrar): We can add these functions into OS dependent files.
#if defined(OS_WIN)
// MessageLoop watcher callback.
void StreamListenSocket::OnObjectSignaled(HANDLE object) {
WSANETWORKEVENTS ev;
if (kSocketError == WSAEnumNetworkEvents(socket_, socket_event_, &ev)) {
// TODO
return;
}
// If both FD_CLOSE and FD_READ are set we only call Read().
// This will cause OnObjectSignaled to be called immediately again
// unless this socket is destroyed in Read().
if ((ev.lNetworkEvents & (FD_CLOSE | FD_READ)) == FD_CLOSE) {
Close();
// Close might have deleted this object. We should return immediately.
return;
}
// The object was reset by WSAEnumNetworkEvents. Watch for the next signal.
watcher_.StartWatchingOnce(object, this);
if (ev.lNetworkEvents == 0) {
// Occasionally the event is set even though there is no new data.
// The net seems to think that this is ignorable.
return;
}
if (ev.lNetworkEvents & FD_ACCEPT) {
Accept();
}
if (ev.lNetworkEvents & FD_READ) {
if (reads_paused_) {
has_pending_reads_ = true;
} else {
Read();
// Read might have deleted this object. We should return immediately.
}
}
}
#elif defined(OS_POSIX)
void StreamListenSocket::OnFileCanReadWithoutBlocking(int fd) {
switch (wait_state_) {
case WAITING_ACCEPT:
Accept();
break;
case WAITING_READ:
if (reads_paused_) {
has_pending_reads_ = true;
} else {
Read();
}
break;
default:
// Close() is called by Read() in the Linux case.
NOTREACHED();
break;
}
}
void StreamListenSocket::OnFileCanWriteWithoutBlocking(int fd) {
// MessagePumpLibevent callback, we don't listen for write events
// so we shouldn't ever reach here.
NOTREACHED();
}
#endif
void StreamListenSocket::PauseReads() {
DCHECK(!reads_paused_);
reads_paused_ = true;
}
void StreamListenSocket::ResumeReads() {
DCHECK(reads_paused_);
reads_paused_ = false;
if (has_pending_reads_) {
has_pending_reads_ = false;
Read();
}
}
} // namespace test_server
} // namespace net

View file

@ -1,152 +0,0 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Stream-based listen socket implementation that handles reading and writing
// to the socket, but does not handle creating the socket nor connecting
// sockets, which are handled by subclasses on creation and in Accept,
// respectively.
// StreamListenSocket handles IO asynchronously in the specified MessageLoop.
// This class is NOT thread safe. It uses WSAEVENT handles to monitor activity
// in a given MessageLoop. This means that callbacks will happen in that loop's
// thread always and that all other methods (including constructor and
// destructor) should also be called from the same thread.
#ifndef NET_TEST_EMBEDDED_TEST_SERVER_STREAM_LISTEN_SOCKET_H_
#define NET_TEST_EMBEDDED_TEST_SERVER_STREAM_LISTEN_SOCKET_H_
#include <memory>
#include "build/build_config.h"
#if defined(OS_WIN)
#include <winsock2.h>
#endif
#include <string>
#if defined(OS_WIN)
#include "base/win/object_watcher.h"
#elif defined(OS_POSIX)
#include "base/message_loop/message_loop.h"
#endif
#include "base/macros.h"
#include "base/compiler_specific.h"
#include "net/base/net_export.h"
#include "net/socket/socket_descriptor.h"
namespace net {
class IPEndPoint;
namespace test_server {
class StreamListenSocket :
#if defined(OS_WIN)
public base::win::ObjectWatcher::Delegate {
#elif defined(OS_POSIX)
public base::MessageLoopForIO::Watcher {
#endif
public:
~StreamListenSocket() override;
// TODO(erikkay): this delegate should really be split into two parts
// to split up the listener from the connected socket. Perhaps this class
// should be split up similarly.
class Delegate {
public:
// |server| is the original listening Socket, connection is the new
// Socket that was created.
virtual void DidAccept(StreamListenSocket* server,
std::unique_ptr<StreamListenSocket> connection) = 0;
virtual void DidRead(StreamListenSocket* connection,
const char* data,
int len) = 0;
virtual void DidClose(StreamListenSocket* sock) = 0;
protected:
virtual ~Delegate() {}
};
// Send data to the socket.
void Send(const char* bytes, int len, bool append_linefeed = false);
void Send(const std::string& str, bool append_linefeed = false);
// Copies the local address to |address|. Returns a network error code.
// This method is virtual to support unit testing.
virtual int GetLocalAddress(IPEndPoint* address) const;
// Copies the peer address to |address|. Returns a network error code.
// This method is virtual to support unit testing.
virtual int GetPeerAddress(IPEndPoint* address) const;
static const int kSocketError;
protected:
enum WaitState { NOT_WAITING = 0, WAITING_ACCEPT = 1, WAITING_READ = 2 };
StreamListenSocket(SocketDescriptor s, Delegate* del);
SocketDescriptor AcceptSocket();
virtual void Accept() = 0;
void Listen();
void Read();
void Close();
void CloseSocket();
// Pass any value in case of Windows, because in Windows
// we are not using state.
void WatchSocket(WaitState state);
void UnwatchSocket();
Delegate* const socket_delegate_;
private:
friend class TransportClientSocketTest;
void SendInternal(const char* bytes, int len);
#if defined(OS_WIN)
// ObjectWatcher delegate.
void OnObjectSignaled(HANDLE object) override;
base::win::ObjectWatcher watcher_;
HANDLE socket_event_;
#elif defined(OS_POSIX)
// Called by MessagePumpLibevent when the socket is ready to do I/O.
void OnFileCanReadWithoutBlocking(int fd) override;
void OnFileCanWriteWithoutBlocking(int fd) override;
WaitState wait_state_;
// The socket's libevent wrapper.
base::MessageLoopForIO::FileDescriptorWatcher watcher_;
#endif
// NOTE: This is for unit test use only!
// Pause/Resume calling Read(). Note that ResumeReads() will also call
// Read() if there is anything to read.
void PauseReads();
void ResumeReads();
const SocketDescriptor socket_;
bool reads_paused_;
bool has_pending_reads_;
DISALLOW_COPY_AND_ASSIGN(StreamListenSocket);
};
// Abstract factory that must be subclassed for each subclass of
// StreamListenSocket.
class StreamListenSocketFactory {
public:
virtual ~StreamListenSocketFactory() {}
// Returns a new instance of StreamListenSocket or NULL if an error occurred.
virtual std::unique_ptr<StreamListenSocket> CreateAndListen(
StreamListenSocket::Delegate* delegate) const = 0;
};
} // namespace test_server
} // namespace net
#endif // NET_TEST_EMBEDDED_TEST_SERVER_STREAM_LISTEN_SOCKET_H_

View file

@ -1,120 +0,0 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/test/embedded_test_server/tcp_listen_socket.h"
#if defined(OS_WIN)
// winsock2.h must be included first in order to ensure it is included before
// windows.h.
#include <winsock2.h>
#include <ws2tcpip.h>
#elif defined(OS_POSIX)
#include <arpa/inet.h>
#include <errno.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include "net/base/net_errors.h"
#endif
#include "base/logging.h"
#include "base/sys_byteorder.h"
#include "base/threading/platform_thread.h"
#include "build/build_config.h"
#include "net/base/network_interfaces.h"
#include "net/base/winsock_init.h"
#include "net/socket/socket_descriptor.h"
using std::string;
namespace net {
namespace test_server {
// static
std::unique_ptr<TCPListenSocket> TCPListenSocket::CreateAndListen(
const string& ip,
uint16_t port,
StreamListenSocket::Delegate* del) {
SocketDescriptor s = CreateAndBind(ip, port);
if (s == kInvalidSocket)
return std::unique_ptr<TCPListenSocket>();
std::unique_ptr<TCPListenSocket> sock(new TCPListenSocket(s, del));
sock->Listen();
return sock;
}
TCPListenSocket::TCPListenSocket(SocketDescriptor s,
StreamListenSocket::Delegate* del)
: StreamListenSocket(s, del) {
}
TCPListenSocket::~TCPListenSocket() {
}
SocketDescriptor TCPListenSocket::CreateAndBind(const string& ip,
uint16_t port) {
SocketDescriptor s = CreatePlatformSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s != kInvalidSocket) {
#if defined(OS_POSIX)
// Allow rapid reuse.
static const int kOn = 1;
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn));
#endif
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(ip.c_str());
addr.sin_port = base::HostToNet16(port);
if (bind(s, reinterpret_cast<sockaddr*>(&addr), sizeof(addr))) {
#if defined(OS_WIN)
closesocket(s);
#elif defined(OS_POSIX)
close(s);
#endif
LOG(ERROR) << "Could not bind socket to " << ip << ":" << port;
s = kInvalidSocket;
}
}
return s;
}
SocketDescriptor TCPListenSocket::CreateAndBindAnyPort(const string& ip,
uint16_t* port) {
SocketDescriptor s = CreateAndBind(ip, 0);
if (s == kInvalidSocket)
return kInvalidSocket;
sockaddr_in addr;
socklen_t addr_size = sizeof(addr);
bool failed = getsockname(s, reinterpret_cast<struct sockaddr*>(&addr),
&addr_size) != 0;
if (addr_size != sizeof(addr))
failed = true;
if (failed) {
LOG(ERROR) << "Could not determine bound port, getsockname() failed";
#if defined(OS_WIN)
closesocket(s);
#elif defined(OS_POSIX)
close(s);
#endif
return kInvalidSocket;
}
*port = base::NetToHost16(addr.sin_port);
return s;
}
void TCPListenSocket::Accept() {
SocketDescriptor conn = AcceptSocket();
if (conn == kInvalidSocket)
return;
std::unique_ptr<TCPListenSocket> sock(new TCPListenSocket(conn, socket_delegate_));
#if defined(OS_POSIX)
sock->WatchSocket(WAITING_READ);
#endif
socket_delegate_->DidAccept(this, std::move(sock));
}
} // namespace test_server
} // namespace net

View file

@ -1,55 +0,0 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_TEST_EMBEDDED_TEST_SERVER_TCP_LISTEN_SOCKET_H_
#define NET_TEST_EMBEDDED_TEST_SERVER_TCP_LISTEN_SOCKET_H_
#include <string>
#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/socket/socket_descriptor.h"
#include "net/test/embedded_test_server/stream_listen_socket.h"
namespace net {
namespace test_server {
// Implements a TCP socket.
class TCPListenSocket : public StreamListenSocket {
public:
~TCPListenSocket() override;
// Listen on port for the specified IP address. Use 127.0.0.1 to only
// accept local connections.
static std::unique_ptr<TCPListenSocket> CreateAndListen(
const std::string& ip,
uint16_t port,
StreamListenSocket::Delegate* del);
protected:
TCPListenSocket(SocketDescriptor s, StreamListenSocket::Delegate* del);
// Implements StreamListenSocket::Accept.
void Accept() override;
private:
friend class EmbeddedTestServer;
friend class TCPListenSocketTester;
// Get raw TCP socket descriptor bound to ip:port.
static SocketDescriptor CreateAndBind(const std::string& ip, uint16_t port);
// Get raw TCP socket descriptor bound to ip and return port it is bound to.
static SocketDescriptor CreateAndBindAnyPort(const std::string& ip,
uint16_t* port);
DISALLOW_COPY_AND_ASSIGN(TCPListenSocket);
};
} // namespace test_server
} // namespace net
#endif // NET_TEST_EMBEDDED_TEST_SERVER_TCP_LISTEN_SOCKET_H_