Merge remote-tracking branch 'upstream/master'

# Conflicts:
#	atom/browser/api/atom_api_web_contents.cc
#	chromium_src/chrome/browser/printing/print_job_worker.cc
#	chromium_src/chrome/browser/printing/print_job_worker.h
#	chromium_src/chrome/browser/printing/print_view_manager_base.cc
#	chromium_src/chrome/browser/printing/print_view_manager_base.h
#	chromium_src/chrome/browser/printing/printer_query.cc
#	chromium_src/chrome/common/print_messages.cc
#	chromium_src/chrome/renderer/printing/print_web_view_helper.cc
This commit is contained in:
renaesop 2017-02-07 09:30:36 +08:00
commit 26135b412b
168 changed files with 1632 additions and 1755 deletions

View file

@ -19,8 +19,7 @@
#include "third_party/libyuv/include/libyuv/scale_argb.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
#include "third_party/webrtc/modules/desktop_capture/window_capturer.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/skia_util.h"
@ -86,8 +85,8 @@ class NativeDesktopMediaList::Worker
: public webrtc::DesktopCapturer::Callback {
public:
Worker(base::WeakPtr<NativeDesktopMediaList> media_list,
std::unique_ptr<webrtc::ScreenCapturer> screen_capturer,
std::unique_ptr<webrtc::WindowCapturer> window_capturer);
std::unique_ptr<webrtc::DesktopCapturer> screen_capturer,
std::unique_ptr<webrtc::DesktopCapturer> window_capturer);
~Worker() override;
void Refresh(const gfx::Size& thumbnail_size,
@ -102,8 +101,8 @@ class NativeDesktopMediaList::Worker
base::WeakPtr<NativeDesktopMediaList> media_list_;
std::unique_ptr<webrtc::ScreenCapturer> screen_capturer_;
std::unique_ptr<webrtc::WindowCapturer> window_capturer_;
std::unique_ptr<webrtc::DesktopCapturer> screen_capturer_;
std::unique_ptr<webrtc::DesktopCapturer> window_capturer_;
std::unique_ptr<webrtc::DesktopFrame> current_frame_;
@ -114,8 +113,8 @@ class NativeDesktopMediaList::Worker
NativeDesktopMediaList::Worker::Worker(
base::WeakPtr<NativeDesktopMediaList> media_list,
std::unique_ptr<webrtc::ScreenCapturer> screen_capturer,
std::unique_ptr<webrtc::WindowCapturer> window_capturer)
std::unique_ptr<webrtc::DesktopCapturer> screen_capturer,
std::unique_ptr<webrtc::DesktopCapturer> window_capturer)
: media_list_(media_list),
screen_capturer_(std::move(screen_capturer)),
window_capturer_(std::move(window_capturer)) {
@ -133,8 +132,8 @@ void NativeDesktopMediaList::Worker::Refresh(
std::vector<SourceDescription> sources;
if (screen_capturer_) {
webrtc::ScreenCapturer::ScreenList screens;
if (screen_capturer_->GetScreenList(&screens)) {
webrtc::DesktopCapturer::SourceList screens;
if (screen_capturer_->GetSourceList(&screens)) {
bool mutiple_screens = screens.size() > 1;
base::string16 title;
for (size_t i = 0; i < screens.size(); ++i) {
@ -150,10 +149,9 @@ void NativeDesktopMediaList::Worker::Refresh(
}
if (window_capturer_) {
webrtc::WindowCapturer::WindowList windows;
if (window_capturer_->GetWindowList(&windows)) {
for (webrtc::WindowCapturer::WindowList::iterator it = windows.begin();
it != windows.end(); ++it) {
webrtc::DesktopCapturer::SourceList windows;
if (window_capturer_->GetSourceList(&windows)) {
for (auto it = windows.begin(); it != windows.end(); ++it) {
// Skip the picker dialog window.
if (it->id != view_dialog_id) {
sources.push_back(SourceDescription(
@ -176,15 +174,15 @@ void NativeDesktopMediaList::Worker::Refresh(
SourceDescription& source = sources[i];
switch (source.id.type) {
case DesktopMediaID::TYPE_SCREEN:
if (!screen_capturer_->SelectScreen(source.id.id))
if (!screen_capturer_->SelectSource(source.id.id))
continue;
screen_capturer_->Capture(webrtc::DesktopRegion());
screen_capturer_->CaptureFrame();
break;
case DesktopMediaID::TYPE_WINDOW:
if (!window_capturer_->SelectWindow(source.id.id))
if (!window_capturer_->SelectSource(source.id.id))
continue;
window_capturer_->Capture(webrtc::DesktopRegion());
window_capturer_->CaptureFrame();
break;
default:
@ -225,8 +223,8 @@ void NativeDesktopMediaList::Worker::OnCaptureResult(
}
NativeDesktopMediaList::NativeDesktopMediaList(
std::unique_ptr<webrtc::ScreenCapturer> screen_capturer,
std::unique_ptr<webrtc::WindowCapturer> window_capturer)
std::unique_ptr<webrtc::DesktopCapturer> screen_capturer,
std::unique_ptr<webrtc::DesktopCapturer> window_capturer)
: screen_capturer_(std::move(screen_capturer)),
window_capturer_(std::move(window_capturer)),
update_period_(base::TimeDelta::FromMilliseconds(kDefaultUpdatePeriod)),

View file

@ -12,8 +12,7 @@
#include "ui/gfx/image/image_skia.h"
namespace webrtc {
class ScreenCapturer;
class WindowCapturer;
class DesktopCapturer;
}
// Implementation of DesktopMediaList that shows native screens and
@ -24,8 +23,8 @@ class NativeDesktopMediaList : public DesktopMediaList {
// types of sources the model should be populated with (e.g. it will only
// contain windows, if |screen_capturer| is NULL).
NativeDesktopMediaList(
std::unique_ptr<webrtc::ScreenCapturer> screen_capturer,
std::unique_ptr<webrtc::WindowCapturer> window_capturer);
std::unique_ptr<webrtc::DesktopCapturer> screen_capturer,
std::unique_ptr<webrtc::DesktopCapturer> window_capturer);
~NativeDesktopMediaList() override;
// DesktopMediaList interface.
@ -65,8 +64,8 @@ class NativeDesktopMediaList : public DesktopMediaList {
void OnRefreshFinished();
// Capturers specified in SetCapturers() and passed to the |worker_| later.
std::unique_ptr<webrtc::ScreenCapturer> screen_capturer_;
std::unique_ptr<webrtc::WindowCapturer> window_capturer_;
std::unique_ptr<webrtc::DesktopCapturer> screen_capturer_;
std::unique_ptr<webrtc::DesktopCapturer> window_capturer_;
// Time interval between mode updates.
base::TimeDelta update_period_;

View file

@ -4,13 +4,22 @@
#include "chrome/browser/printing/pdf_to_emf_converter.h"
#include <stdint.h>
#include <windows.h>
#include <memory>
#include <queue>
#include <utility>
#include <vector>
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#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 "content/public/browser/browser_thread.h"
@ -19,6 +28,7 @@
#include "content/public/browser/utility_process_host_client.h"
#include "printing/emf_win.h"
#include "printing/pdf_render_settings.h"
#include "ui/base/l10n/l10n_util.h"
namespace printing {
@ -38,7 +48,7 @@ class RefCountedTempDir
public:
RefCountedTempDir() { ignore_result(temp_dir_.CreateUniqueTempDir()); }
bool IsValid() const { return temp_dir_.IsValid(); }
const base::FilePath& GetPath() const { return temp_dir_.path(); }
const base::FilePath& GetPath() const { return temp_dir_.GetPath(); }
private:
friend struct BrowserThread::DeleteOnThread<BrowserThread::FILE>;
@ -59,7 +69,9 @@ typedef std::unique_ptr<base::File, BrowserThread::DeleteOnFileThread>
class LazyEmf : public MetafilePlayer {
public:
LazyEmf(const scoped_refptr<RefCountedTempDir>& temp_dir, ScopedTempFile file)
: temp_dir_(temp_dir), file_(std::move(file)) {}
: temp_dir_(temp_dir), file_(std::move(file)) {
CHECK(file_);
}
~LazyEmf() override { Close(); }
bool SafePlayback(HDC hdc) const override;
@ -97,6 +109,7 @@ class PdfToEmfUtilityProcessHostClient
const PdfRenderSettings& settings);
void Start(const scoped_refptr<base::RefCountedMemory>& data,
bool print_text_with_gdi,
const PdfToEmfConverter::StartCallback& start_callback);
void GetPage(int page_number,
@ -104,10 +117,14 @@ class PdfToEmfUtilityProcessHostClient
void Stop();
// Needs to be public to handle ChromeUtilityHostMsg_PreCacheFontCharacters
// sync message replies.
bool Send(IPC::Message* msg);
// UtilityProcessHostClient implementation.
virtual void OnProcessCrashed(int exit_code) override;
virtual void OnProcessLaunchFailed(int exit_code) override;
virtual bool OnMessageReceived(const IPC::Message& message) override;
void OnProcessCrashed(int exit_code) override;
void OnProcessLaunchFailed(int exit_code) override;
bool OnMessageReceived(const IPC::Message& message) override;
private:
class GetPageCallbackData {
@ -138,19 +155,20 @@ class PdfToEmfUtilityProcessHostClient
int page_number_;
PdfToEmfConverter::GetPageCallback callback_;
ScopedTempFile emf_;
DISALLOW_COPY_AND_ASSIGN(GetPageCallbackData);
};
virtual ~PdfToEmfUtilityProcessHostClient();
bool Send(IPC::Message* msg);
~PdfToEmfUtilityProcessHostClient() override;
// Message handlers.
void OnProcessStarted();
void OnPageCount(int page_count);
void OnPageDone(bool success, float scale_factor);
void OnPreCacheFontCharacters(const LOGFONT& log_font,
const base::string16& characters);
void OnFailed();
void OnTempPdfReady(ScopedTempFile pdf);
void OnTempPdfReady(bool print_text_with_gdi, ScopedTempFile pdf);
void OnTempEmfReady(GetPageCallbackData* callback_data, ScopedTempFile emf);
scoped_refptr<RefCountedTempDir> temp_dir_;
@ -158,7 +176,6 @@ class PdfToEmfUtilityProcessHostClient
// Used to suppress callbacks after PdfToEmfConverterImpl is deleted.
base::WeakPtr<PdfToEmfConverterImpl> converter_;
PdfRenderSettings settings_;
scoped_refptr<base::RefCountedMemory> data_;
// Document loaded callback.
PdfToEmfConverter::StartCallback start_callback_;
@ -179,14 +196,15 @@ class PdfToEmfConverterImpl : public PdfToEmfConverter {
public:
PdfToEmfConverterImpl();
virtual ~PdfToEmfConverterImpl();
~PdfToEmfConverterImpl() override;
virtual void Start(const scoped_refptr<base::RefCountedMemory>& data,
const PdfRenderSettings& conversion_settings,
const StartCallback& start_callback) override;
void Start(const scoped_refptr<base::RefCountedMemory>& data,
const PdfRenderSettings& conversion_settings,
bool print_text_with_gdi,
const StartCallback& start_callback) override;
virtual void GetPage(int page_number,
const GetPageCallback& get_page_callback) override;
void GetPage(int page_number,
const GetPageCallback& get_page_callback) override;
// Helps to cancel callbacks if this object is destroyed.
void RunCallback(const base::Closure& callback);
@ -205,16 +223,21 @@ ScopedTempFile CreateTempFile(scoped_refptr<RefCountedTempDir>* temp_dir) {
if (!(*temp_dir)->IsValid())
return file;
base::FilePath path;
if (!base::CreateTemporaryFileInDir((*temp_dir)->GetPath(), &path))
if (!base::CreateTemporaryFileInDir((*temp_dir)->GetPath(), &path)) {
PLOG(ERROR) << "Failed to create file in "
<< (*temp_dir)->GetPath().value();
return file;
}
file.reset(new base::File(path,
base::File::FLAG_CREATE_ALWAYS |
base::File::FLAG_WRITE |
base::File::FLAG_READ |
base::File::FLAG_DELETE_ON_CLOSE |
base::File::FLAG_TEMPORARY));
if (!file->IsValid())
if (!file->IsValid()) {
PLOG(ERROR) << "Failed to create " << path.value();
file.reset();
}
return file;
}
@ -228,6 +251,7 @@ ScopedTempFile CreateTempPdfFile(
static_cast<int>(data->size()) !=
pdf_file->WriteAtCurrentPos(data->front_as<char>(), data->size())) {
pdf_file.reset();
return pdf_file;
}
pdf_file->Seek(base::File::FROM_BEGIN, 0);
return pdf_file;
@ -281,17 +305,15 @@ PdfToEmfUtilityProcessHostClient::~PdfToEmfUtilityProcessHostClient() {
void PdfToEmfUtilityProcessHostClient::Start(
const scoped_refptr<base::RefCountedMemory>& data,
bool print_text_with_gdi,
const PdfToEmfConverter::StartCallback& start_callback) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
BrowserThread::PostTask(BrowserThread::IO,
FROM_HERE,
base::Bind(&PdfToEmfUtilityProcessHostClient::Start,
this,
data,
start_callback));
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&PdfToEmfUtilityProcessHostClient::Start, this, data,
print_text_with_gdi, start_callback));
return;
}
data_ = data;
// Store callback before any OnFailed() call to make it called on failure.
start_callback_ = start_callback;
@ -299,37 +321,28 @@ void PdfToEmfUtilityProcessHostClient::Start(
// NOTE: This process _must_ be sandboxed, otherwise the pdf dll will load
// gdiplus.dll, change how rendering happens, and not be able to correctly
// generate when sent to a metafile DC.
utility_process_host_ =
content::UtilityProcessHost::Create(
this, base::MessageLoop::current()->task_runner())->AsWeakPtr();
if (!utility_process_host_)
return OnFailed();
// Should reply with OnProcessStarted().
Send(new ChromeUtilityMsg_StartupPing);
}
utility_process_host_ = content::UtilityProcessHost::Create(
this, base::ThreadTaskRunnerHandle::Get())
->AsWeakPtr();
utility_process_host_->SetName(base::ASCIIToUTF16(
"IDS_UTILITY_PROCESS_EMF_CONVERTOR_NAME"));
void PdfToEmfUtilityProcessHostClient::OnProcessStarted() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!utility_process_host_)
return OnFailed();
scoped_refptr<base::RefCountedMemory> data = data_;
data_ = NULL;
BrowserThread::PostTaskAndReplyWithResult(
BrowserThread::FILE,
FROM_HERE,
BrowserThread::FILE, FROM_HERE,
base::Bind(&CreateTempPdfFile, data, &temp_dir_),
base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempPdfReady, this));
base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempPdfReady, this,
print_text_with_gdi));
}
void PdfToEmfUtilityProcessHostClient::OnTempPdfReady(ScopedTempFile pdf) {
void PdfToEmfUtilityProcessHostClient::OnTempPdfReady(bool print_text_with_gdi,
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_));
IPC::GetPlatformFileForTransit(pdf->GetPlatformFile(), false), settings_,
print_text_with_gdi));
}
void PdfToEmfUtilityProcessHostClient::OnPageCount(int page_count) {
@ -413,6 +426,38 @@ void PdfToEmfUtilityProcessHostClient::OnPageDone(bool success,
get_page_callbacks_.pop();
}
void PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters(
const LOGFONT& font,
const base::string16& str) {
// TODO(scottmg): pdf/ppapi still require the renderer to be able to precache
// GDI fonts (http://crbug.com/383227), even when using DirectWrite.
// Eventually this shouldn't be added and should be moved to
// FontCacheDispatcher too. http://crbug.com/356346.
// First, comments from FontCacheDispatcher::OnPreCacheFont do apply here too.
// Except that for True Type fonts,
// GetTextMetrics will not load the font in memory.
// The only way windows seem to load properly, it is to create a similar
// device (like the one in which we print), then do an ExtTextOut,
// as we do in the printing thread, which is sandboxed.
HDC hdc = CreateEnhMetaFile(nullptr, nullptr, nullptr, nullptr);
HFONT font_handle = CreateFontIndirect(&font);
DCHECK(font_handle != nullptr);
HGDIOBJ old_font = SelectObject(hdc, font_handle);
DCHECK(old_font != nullptr);
ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, str.c_str(), str.length(), nullptr);
SelectObject(hdc, old_font);
DeleteObject(font_handle);
HENHMETAFILE metafile = CloseEnhMetaFile(hdc);
if (metafile)
DeleteEnhMetaFile(metafile);
}
void PdfToEmfUtilityProcessHostClient::Stop() {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
BrowserThread::PostTask(
@ -436,11 +481,12 @@ bool PdfToEmfUtilityProcessHostClient::OnMessageReceived(
const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(PdfToEmfUtilityProcessHostClient, message)
IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ProcessStarted, OnProcessStarted)
IPC_MESSAGE_HANDLER(
ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount, OnPageCount)
IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone,
OnPageDone)
IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_PreCacheFontCharacters,
OnPreCacheFontCharacters)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@ -473,11 +519,12 @@ PdfToEmfConverterImpl::~PdfToEmfConverterImpl() {
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, start_callback);
utility_client_->Start(data, print_text_with_gdi, start_callback);
}
void PdfToEmfConverterImpl::GetPage(int page_number,

View file

@ -10,21 +10,18 @@
#include "base/callback.h"
#include "base/memory/ref_counted_memory.h"
namespace base {
class FilePath;
}
namespace printing {
class MetafilePlayer;
class PdfRenderSettings;
struct PdfRenderSettings;
class PdfToEmfConverter {
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;
std::unique_ptr<MetafilePlayer> emf)>
GetPageCallback;
virtual ~PdfToEmfConverter();
@ -34,6 +31,7 @@ class PdfToEmfConverter {
// 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;
// Requests conversion of the page. |page_number| is 0-base page number in

View file

@ -4,14 +4,20 @@
#include "chrome/browser/printing/print_job.h"
#include <memory>
#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/threading/worker_pool.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/printing/print_job_worker.h"
#include "content/public/browser/browser_thread.h"
@ -24,25 +30,22 @@
#include "printing/pdf_render_settings.h"
#endif
using base::TimeDelta;
namespace printing {
namespace {
// Helper function to ensure |owner| is valid until at least |callback| returns.
void HoldRefCallback(const scoped_refptr<printing::PrintJobWorkerOwner>& owner,
void HoldRefCallback(const scoped_refptr<PrintJobWorkerOwner>& owner,
const base::Closure& callback) {
callback.Run();
}
} // namespace
namespace printing {
PrintJob::PrintJob()
: source_(NULL),
worker_(),
settings_(),
: source_(nullptr),
is_job_pending_(false),
is_canceling_(false),
quit_factory_(this) {
@ -65,12 +68,12 @@ void PrintJob::Initialize(PrintJobWorkerOwner* job,
PrintedPagesSource* source,
int page_count) {
DCHECK(!source_);
DCHECK(!worker_.get());
DCHECK(!worker_);
DCHECK(!is_job_pending_);
DCHECK(!is_canceling_);
DCHECK(!document_.get());
source_ = source;
worker_.reset(job->DetachWorker(this));
worker_ = job->DetachWorker(this);
settings_ = job->settings();
PrintedDocument* new_doc =
@ -90,15 +93,9 @@ void PrintJob::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
DCHECK(RunsTasksOnCurrentThread());
switch (type) {
case chrome::NOTIFICATION_PRINT_JOB_EVENT: {
OnNotifyPrintJobEvent(*content::Details<JobEventDetails>(details).ptr());
break;
}
default: {
break;
}
}
DCHECK_EQ(chrome::NOTIFICATION_PRINT_JOB_EVENT, type);
OnNotifyPrintJobEvent(*content::Details<JobEventDetails>(details).ptr());
}
void PrintJob::GetSettingsDone(const PrintSettings& new_settings,
@ -106,9 +103,10 @@ void PrintJob::GetSettingsDone(const PrintSettings& new_settings,
NOTREACHED();
}
PrintJobWorker* PrintJob::DetachWorker(PrintJobWorkerOwner* new_owner) {
std::unique_ptr<PrintJobWorker> PrintJob::DetachWorker(
PrintJobWorkerOwner* new_owner) {
NOTREACHED();
return NULL;
return nullptr;
}
const PrintSettings& PrintJob::settings() const {
@ -116,23 +114,22 @@ const PrintSettings& PrintJob::settings() const {
}
int PrintJob::cookie() const {
// Always use an invalid cookie in this case.
if (!document_.get())
// Always use an invalid cookie in this case.
return 0;
return document_->cookie();
}
void PrintJob::StartPrinting() {
DCHECK(RunsTasksOnCurrentThread());
DCHECK(worker_->IsRunning());
DCHECK(!is_job_pending_);
if (!worker_->IsRunning() || is_job_pending_)
if (!worker_->IsRunning() || is_job_pending_) {
NOTREACHED();
return;
}
// Real work is done in PrintJobWorker::StartPrinting().
worker_->PostTask(FROM_HERE,
base::Bind(&HoldRefCallback,
make_scoped_refptr(this),
base::Bind(&HoldRefCallback, make_scoped_refptr(this),
base::Bind(&PrintJobWorker::StartPrinting,
base::Unretained(worker_.get()),
base::RetainedRef(document_))));
@ -141,7 +138,7 @@ void PrintJob::StartPrinting() {
// Tell everyone!
scoped_refptr<JobEventDetails> details(
new JobEventDetails(JobEventDetails::NEW_DOC, document_.get(), NULL));
new JobEventDetails(JobEventDetails::NEW_DOC, document_.get(), nullptr));
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_PRINT_JOB_EVENT,
content::Source<PrintJob>(this),
@ -165,7 +162,8 @@ void PrintJob::Stop() {
ControlledWorkerShutdown();
} else {
// Flush the cached document.
UpdatePrintedDocument(NULL);
is_job_pending_ = false;
UpdatePrintedDocument(nullptr);
}
}
@ -185,7 +183,7 @@ void PrintJob::Cancel() {
}
// Make sure a Cancel() is broadcast.
scoped_refptr<JobEventDetails> details(
new JobEventDetails(JobEventDetails::FAILED, NULL, NULL));
new JobEventDetails(JobEventDetails::FAILED, nullptr, nullptr));
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_PRINT_JOB_EVENT,
content::Source<PrintJob>(this),
@ -210,7 +208,7 @@ bool PrintJob::FlushJob(base::TimeDelta timeout) {
}
void PrintJob::DisconnectSource() {
source_ = NULL;
source_ = nullptr;
if (document_.get())
document_->DisconnectSource();
}
@ -237,8 +235,10 @@ class PrintJob::PdfToEmfState {
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, start_callback);
converter_->Start(data, conversion_settings, print_text_with_gdi,
start_callback);
}
void GetMorePages(
@ -273,48 +273,51 @@ class PrintJob::PdfToEmfState {
std::unique_ptr<PdfToEmfConverter> converter_;
};
void PrintJob::AppendPrintedPage(int page_number) {
pdf_page_mapping_.push_back(page_number);
}
void PrintJob::StartPdfToEmfConversion(
const scoped_refptr<base::RefCountedMemory>& bytes,
const gfx::Size& page_size,
const gfx::Rect& content_area) {
DCHECK(!ptd_to_emf_state_.get());
ptd_to_emf_state_.reset(new PdfToEmfState(page_size, content_area));
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);
const int kPrinterDpi = settings().dpi();
ptd_to_emf_state_->Start(
bytes,
printing::PdfRenderSettings(content_area, kPrinterDpi, true),
base::Bind(&PrintJob::OnPdfToEmfStarted, this));
pdf_to_emf_state_->Start(
bytes, PdfRenderSettings(content_area, kPrinterDpi, true),
print_text_with_gdi, base::Bind(&PrintJob::OnPdfToEmfStarted, this));
}
void PrintJob::OnPdfToEmfStarted(int page_count) {
if (page_count <= 0) {
ptd_to_emf_state_.reset();
pdf_to_emf_state_.reset();
Cancel();
return;
}
ptd_to_emf_state_->set_page_count(page_count);
ptd_to_emf_state_->GetMorePages(
pdf_to_emf_state_->set_page_count(page_count);
pdf_to_emf_state_->GetMorePages(
base::Bind(&PrintJob::OnPdfToEmfPageConverted, this));
}
void PrintJob::OnPdfToEmfPageConverted(int page_number,
float scale_factor,
std::unique_ptr<MetafilePlayer> emf) {
DCHECK(ptd_to_emf_state_);
if (!document_.get() || !emf) {
ptd_to_emf_state_.reset();
DCHECK(pdf_to_emf_state_);
if (!document_.get() || !emf || page_number < 0 ||
static_cast<size_t>(page_number) >= pdf_page_mapping_.size()) {
pdf_to_emf_state_.reset();
Cancel();
return;
}
// Update the rendered document. It will send notifications to the listener.
document_->SetPage(page_number,
std::move(emf),
scale_factor,
ptd_to_emf_state_->page_size(),
ptd_to_emf_state_->content_area());
document_->SetPage(pdf_page_mapping_[page_number], std::move(emf),
scale_factor, pdf_to_emf_state_->page_size(),
pdf_to_emf_state_->content_area());
ptd_to_emf_state_->GetMorePages(
pdf_to_emf_state_->GetMorePages(
base::Bind(&PrintJob::OnPdfToEmfPageConverted, this));
}
@ -326,16 +329,14 @@ void PrintJob::UpdatePrintedDocument(PrintedDocument* new_document) {
document_ = new_document;
if (document_.get()) {
if (document_.get())
settings_ = document_->settings();
}
if (worker_) {
DCHECK(!is_job_pending_);
// Sync the document with the worker.
worker_->PostTask(FROM_HERE,
base::Bind(&HoldRefCallback,
make_scoped_refptr(this),
base::Bind(&HoldRefCallback, make_scoped_refptr(this),
base::Bind(&PrintJobWorker::OnDocumentChanged,
base::Unretained(worker_.get()),
base::RetainedRef(document_))));
@ -371,9 +372,9 @@ void PrintJob::OnNotifyPrintJobEvent(const JobEventDetails& event_details) {
}
case JobEventDetails::PAGE_DONE:
#if defined(OS_WIN)
ptd_to_emf_state_->OnPageProcessed(
pdf_to_emf_state_->OnPageProcessed(
base::Bind(&PrintJob::OnPdfToEmfPageConverted, this));
#endif // OS_WIN
#endif // defined(OS_WIN)
break;
default: {
NOTREACHED();
@ -391,7 +392,7 @@ void PrintJob::OnDocumentDone() {
Stop();
scoped_refptr<JobEventDetails> details(
new JobEventDetails(JobEventDetails::JOB_DONE, document_.get(), NULL));
new JobEventDetails(JobEventDetails::JOB_DONE, document_.get(), nullptr));
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_PRINT_JOB_EVENT,
content::Source<PrintJob>(this),
@ -418,9 +419,8 @@ void PrintJob::ControlledWorkerShutdown() {
// Delay shutdown until the worker terminates. We want this code path
// to wait on the thread to quit before continuing.
if (worker_->IsRunning()) {
base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&PrintJob::ControlledWorkerShutdown, this),
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, base::Bind(&PrintJob::ControlledWorkerShutdown, this),
base::TimeDelta::FromMilliseconds(100));
return;
}
@ -437,7 +437,7 @@ void PrintJob::ControlledWorkerShutdown() {
is_job_pending_ = false;
registrar_.RemoveAll();
UpdatePrintedDocument(NULL);
UpdatePrintedDocument(nullptr);
}
void PrintJob::HoldUntilStopIsCalled() {

View file

@ -6,15 +6,15 @@
#define CHROME_BROWSER_PRINTING_PRINT_JOB_H_
#include <memory>
#include <vector>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "build/build_config.h"
#include "chrome/browser/printing/print_job_worker_owner.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
class Thread;
namespace base {
class RefCountedMemory;
}
@ -49,16 +49,17 @@ class PrintJob : public PrintJobWorkerOwner,
int page_count);
// content::NotificationObserver implementation.
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) override;
void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) override;
// PrintJobWorkerOwner implementation.
virtual void GetSettingsDone(const PrintSettings& new_settings,
PrintingContext::Result result) override;
virtual PrintJobWorker* DetachWorker(PrintJobWorkerOwner* new_owner) override;
virtual const PrintSettings& settings() const override;
virtual int cookie() const override;
void GetSettingsDone(const PrintSettings& new_settings,
PrintingContext::Result result) override;
std::unique_ptr<PrintJobWorker> DetachWorker(
PrintJobWorkerOwner* new_owner) override;
const PrintSettings& settings() const override;
int cookie() const override;
// Starts the actual printing. Signals the worker that it should begin to
// spool as soon as data is available.
@ -91,23 +92,21 @@ class PrintJob : public PrintJobWorkerOwner,
PrintedDocument* document() const;
#if defined(OS_WIN)
// Let the PrintJob know the 0-based |page_number| of a given printed page.
void AppendPrintedPage(int page_number);
void StartPdfToEmfConversion(
const scoped_refptr<base::RefCountedMemory>& bytes,
const gfx::Size& page_size,
const gfx::Rect& content_area);
void OnPdfToEmfStarted(int page_count);
void OnPdfToEmfPageConverted(int page_number,
float scale_factor,
std::unique_ptr<MetafilePlayer> emf);
#endif // OS_WIN
const gfx::Rect& content_area,
bool print_text_with_gdi);
#endif // defined(OS_WIN)
protected:
virtual ~PrintJob();
~PrintJob() override;
private:
// Updates document_ to a new instance.
// Updates |document_| to a new instance.
void UpdatePrintedDocument(PrintedDocument* new_document);
// Processes a NOTIFY_PRINT_JOB_EVENT notification.
@ -126,6 +125,13 @@ 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);
#endif // defined(OS_WIN)
content::NotificationRegistrar registrar_;
// Source that generates the PrintedPage's (i.e. a WebContents). It will be
@ -152,8 +158,9 @@ class PrintJob : public PrintJobWorkerOwner,
#if defined(OS_WIN)
class PdfToEmfState;
std::unique_ptr<PdfToEmfState> ptd_to_emf_state_;
#endif // OS_WIN
std::unique_ptr<PdfToEmfState> pdf_to_emf_state_;
std::vector<int> pdf_page_mapping_;
#endif // defined(OS_WIN)
// Used at shutdown so that we can quit a nested message loop.
base::WeakPtrFactory<PrintJob> quit_factory_;

View file

@ -35,7 +35,7 @@ scoped_refptr<PrinterQuery> PrintQueriesQueue::PopPrinterQuery(
for (PrinterQueries::iterator itr = queued_queries_.begin();
itr != queued_queries_.end(); ++itr) {
if ((*itr)->cookie() == document_cookie && !(*itr)->is_callback_pending()) {
scoped_refptr<printing::PrinterQuery> current_query(*itr);
scoped_refptr<PrinterQuery> current_query(*itr);
queued_queries_.erase(itr);
DCHECK(current_query->is_valid());
return current_query;
@ -46,10 +46,9 @@ scoped_refptr<PrinterQuery> PrintQueriesQueue::PopPrinterQuery(
scoped_refptr<PrinterQuery> PrintQueriesQueue::CreatePrinterQuery(
int render_process_id,
int render_view_id) {
scoped_refptr<PrinterQuery> job =
new printing::PrinterQuery(render_process_id, render_view_id);
return job;
int render_frame_id) {
return make_scoped_refptr(
new PrinterQuery(render_process_id, render_frame_id));
}
void PrintQueriesQueue::Shutdown() {
@ -76,14 +75,14 @@ PrintJobManager::~PrintJobManager() {
}
scoped_refptr<PrintQueriesQueue> PrintJobManager::queue() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (!queue_.get())
queue_ = new PrintQueriesQueue();
return queue_;
}
void PrintJobManager::Shutdown() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(!is_shutdown_);
is_shutdown_ = true;
registrar_.RemoveAll();
@ -94,7 +93,7 @@ void PrintJobManager::Shutdown() {
}
void PrintJobManager::StopJobs(bool wait_for_finish) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
// Copy the array since it can be modified in transit.
PrintJobs to_stop;
to_stop.swap(current_jobs_);
@ -111,18 +110,11 @@ void PrintJobManager::StopJobs(bool wait_for_finish) {
void PrintJobManager::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
switch (type) {
case chrome::NOTIFICATION_PRINT_JOB_EVENT: {
OnPrintJobEvent(content::Source<PrintJob>(source).ptr(),
*content::Details<JobEventDetails>(details).ptr());
break;
}
default: {
NOTREACHED();
break;
}
}
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK_EQ(chrome::NOTIFICATION_PRINT_JOB_EVENT, type);
OnPrintJobEvent(content::Source<PrintJob>(source).ptr(),
*content::Details<JobEventDetails>(details).ptr());
}
void PrintJobManager::OnPrintJobEvent(

View file

@ -10,6 +10,7 @@
#include <vector>
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/synchronization/lock.h"
#include "base/threading/non_thread_safe.h"
@ -37,7 +38,7 @@ class PrintQueriesQueue : public base::RefCountedThreadSafe<PrintQueriesQueue> {
// Creates new query.
scoped_refptr<PrinterQuery> CreatePrinterQuery(int render_process_id,
int render_view_id);
int render_frame_id);
void Shutdown();
@ -58,15 +59,15 @@ class PrintQueriesQueue : public base::RefCountedThreadSafe<PrintQueriesQueue> {
class PrintJobManager : public content::NotificationObserver {
public:
PrintJobManager();
virtual ~PrintJobManager();
~PrintJobManager() override;
// On browser quit, we should wait to have the print job finished.
void Shutdown();
// content::NotificationObserver
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) override;
void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) override;
// Returns queries queue. Never returns NULL. Must be called on Browser UI
// Thread. Reference could be stored and used from any thread.

View file

@ -4,19 +4,25 @@
#include "chrome/browser/printing/print_job_worker.h"
#include <memory>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/printing/print_job.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "printing/print_job_constants.h"
#include "printing/printed_document.h"
@ -27,7 +33,6 @@
#include <stddef.h>
#include <algorithm>
#include <cmath>
#include <memory>
#include <string>
#include <utility>
@ -46,7 +51,7 @@ namespace printing {
namespace {
// Helper function to ensure |owner| is valid until at least |callback| returns.
void HoldRefCallback(const scoped_refptr<printing::PrintJobWorkerOwner>& owner,
void HoldRefCallback(const scoped_refptr<PrintJobWorkerOwner>& owner,
const base::Closure& callback) {
callback.Run();
}
@ -128,34 +133,38 @@ void PrintSettingsToJobSettings(const PrintSettings& settings,
class PrintingContextDelegate : public PrintingContext::Delegate {
public:
PrintingContextDelegate(int render_process_id, int render_view_id);
virtual ~PrintingContextDelegate();
PrintingContextDelegate(int render_process_id, int render_frame_id);
~PrintingContextDelegate() override;
virtual gfx::NativeView GetParentView() override;
virtual std::string GetAppLocale() override;
gfx::NativeView GetParentView() override;
std::string GetAppLocale() override;
// Not exposed to PrintingContext::Delegate because of dependency issues.
content::WebContents* GetWebContents();
private:
int render_process_id_;
int render_view_id_;
const int render_process_id_;
const int render_frame_id_;
};
PrintingContextDelegate::PrintingContextDelegate(int render_process_id,
int render_view_id)
int render_frame_id)
: render_process_id_(render_process_id),
render_view_id_(render_view_id) {
}
render_frame_id_(render_frame_id) {}
PrintingContextDelegate::~PrintingContextDelegate() {
}
gfx::NativeView PrintingContextDelegate::GetParentView() {
content::WebContents* wc = GetWebContents();
return wc ? wc->GetNativeView() : nullptr;
}
content::WebContents* PrintingContextDelegate::GetWebContents() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
content::RenderViewHost* view =
content::RenderViewHost::FromID(render_process_id_, render_view_id_);
if (!view)
return NULL;
content::WebContents* wc = content::WebContents::FromRenderViewHost(view);
return wc ? wc->GetNativeView() : NULL;
auto* rfh =
content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
return rfh ? content::WebContents::FromRenderFrameHost(rfh) : nullptr;
}
std::string PrintingContextDelegate::GetAppLocale() {
@ -174,17 +183,24 @@ void NotificationCallback(PrintJobWorkerOwner* print_job,
content::Details<JobEventDetails>(details));
}
void PostOnOwnerThread(const scoped_refptr<PrintJobWorkerOwner>& owner,
const PrintingContext::PrintSettingsCallback& callback,
PrintingContext::Result result) {
owner->PostTask(FROM_HERE, base::Bind(&HoldRefCallback, owner,
base::Bind(callback, result)));
}
} // namespace
PrintJobWorker::PrintJobWorker(int render_process_id,
int render_view_id,
int render_frame_id,
PrintJobWorkerOwner* owner)
: owner_(owner), thread_("Printing_Worker"), weak_factory_(this) {
// The object is created in the IO thread.
DCHECK(owner_->RunsTasksOnCurrentThread());
printing_context_delegate_.reset(
new PrintingContextDelegate(render_process_id, render_view_id));
printing_context_delegate_ = base::MakeUnique<PrintingContextDelegate>(
render_process_id, render_frame_id);
printing_context_ = PrintingContext::Create(printing_context_delegate_.get());
}
@ -201,12 +217,13 @@ void PrintJobWorker::SetNewOwner(PrintJobWorkerOwner* new_owner) {
owner_ = new_owner;
}
void PrintJobWorker::GetSettings(
bool ask_user_for_settings,
int document_page_count,
bool has_selection,
MarginType margin_type,
const base::string16& device_name) {
void PrintJobWorker::GetSettings(bool ask_user_for_settings,
int document_page_count,
bool has_selection,
MarginType margin_type,
bool is_scripted,
bool is_modifiable,
const base::string16& device_name) {
DCHECK(task_runner_->RunsTasksOnCurrentThread());
DCHECK_EQ(page_number_, PageNumber::npos());
@ -217,6 +234,7 @@ void PrintJobWorker::GetSettings(
// should happen on the same thread. See http://crbug.com/73466
// MessageLoop::current()->SetNestableTasksAllowed(true);
printing_context_->set_margin_type(margin_type);
printing_context_->set_is_modifiable(is_modifiable);
// When we delegate to a destination, we don't ask the user for settings.
// TODO(mad): Ask the destination for settings.
@ -227,7 +245,8 @@ void PrintJobWorker::GetSettings(
base::Bind(&PrintJobWorker::GetSettingsWithUI,
base::Unretained(this),
document_page_count,
has_selection)));
has_selection,
is_scripted)));
} else if (!device_name.empty()) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
@ -286,23 +305,16 @@ void PrintJobWorker::GetSettingsDone(PrintingContext::Result result) {
void PrintJobWorker::GetSettingsWithUI(
int document_page_count,
bool has_selection) {
bool has_selection,
bool is_scripted) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
printing_context_->AskUserForSettings(
document_page_count,
has_selection,
false,
base::Bind(&PrintJobWorker::GetSettingsWithUIDone,
base::Unretained(this)));
}
void PrintJobWorker::GetSettingsWithUIDone(PrintingContext::Result result) {
PostTask(FROM_HERE,
base::Bind(&HoldRefCallback,
make_scoped_refptr(owner_),
base::Bind(&PrintJobWorker::GetSettingsDone,
base::Unretained(this),
result)));
// weak_factory_ creates pointers valid only on owner_ thread.
printing_context_->AskUserForSettings(
document_page_count, has_selection, is_scripted,
base::Bind(&PostOnOwnerThread, make_scoped_refptr(owner_),
base::Bind(&PrintJobWorker::GetSettingsDone,
weak_factory_.GetWeakPtr())));
}
void PrintJobWorker::UseDefaultSettings() {
@ -331,8 +343,6 @@ void PrintJobWorker::StartPrinting(PrintedDocument* new_document) {
base::string16 document_name =
printing::SimplifyDocumentTitle(document_->name());
if (document_name.empty()) {
}
PrintingContext::Result result =
printing_context_->NewDocument(document_name);
if (result != PrintingContext::OK) {
@ -458,10 +468,11 @@ void PrintJobWorker::SpoolPage(PrintedPage* page) {
DCHECK_NE(page_number_, PageNumber::npos());
// Signal everyone that the page is about to be printed.
owner_->PostTask(FROM_HERE,
base::Bind(&NotificationCallback, base::RetainedRef(owner_),
JobEventDetails::NEW_PAGE, base::RetainedRef(document_),
base::RetainedRef(page)));
owner_->PostTask(
FROM_HERE,
base::Bind(&NotificationCallback, base::RetainedRef(owner_),
JobEventDetails::NEW_PAGE, base::RetainedRef(document_),
base::RetainedRef(page)));
// Preprocess.
if (printing_context_->NewPage() != PrintingContext::OK) {
@ -496,11 +507,10 @@ void PrintJobWorker::OnFailure() {
// We may loose our last reference by broadcasting the FAILED event.
scoped_refptr<PrintJobWorkerOwner> handle(owner_);
owner_->PostTask(
FROM_HERE,
base::Bind(&NotificationCallback, base::RetainedRef(owner_),
JobEventDetails::FAILED,
base::RetainedRef(document_), nullptr));
owner_->PostTask(FROM_HERE,
base::Bind(&NotificationCallback, base::RetainedRef(owner_),
JobEventDetails::FAILED,
base::RetainedRef(document_), nullptr));
Cancel();
// Makes sure the variables are reinitialized.

View file

@ -7,9 +7,11 @@
#include <memory>
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread.h"
#include "chrome/browser/printing/printer_query.h"
#include "content/public/browser/browser_thread.h"
#include "printing/page_number.h"
#include "printing/print_job_constants.h"
@ -34,20 +36,23 @@ class PrintedPage;
class PrintJobWorker {
public:
PrintJobWorker(int render_process_id,
int render_view_id,
int render_frame_id,
PrintJobWorkerOwner* owner);
virtual ~PrintJobWorker();
void SetNewOwner(PrintJobWorkerOwner* new_owner);
// Initializes the print settings. If |ask_user_for_settings| is true, a
// Print... dialog box will be shown to ask the user his preference.
void GetSettings(
bool ask_user_for_settings,
int document_page_count,
bool has_selection,
MarginType margin_type,
const base::string16& device_name);
// Print... dialog box will be shown to ask the user their preference.
// |is_scripted| should be true for calls coming straight from window.print().
// |is_modifiable| implies HTML and not other formats like PDF.
void GetSettings(bool ask_user_for_settings,
int document_page_count,
bool has_selection,
MarginType margin_type,
bool is_scripted,
bool is_modifiable,
const base::string16& device_name);
// Set the new print settings.
void SetSettings(std::unique_ptr<base::DictionaryValue> new_settings);
@ -110,12 +115,8 @@ class PrintJobWorker {
// but sticks with this for consistency.
void GetSettingsWithUI(
int document_page_count,
bool has_selection);
// The callback used by PrintingContext::GetSettingsWithUI() to notify this
// object that the print settings are set. This is needed in order to bounce
// back into the IO thread for GetSettingsDone().
void GetSettingsWithUIDone(PrintingContext::Result result);
bool has_selection,
bool is_scripted);
// Called on the UI thread to update the print settings.
void UpdatePrintSettings(std::unique_ptr<base::DictionaryValue> new_settings);

View file

@ -4,13 +4,14 @@
#include "chrome/browser/printing/print_job_worker_owner.h"
#include "base/message_loop/message_loop.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
namespace printing {
PrintJobWorkerOwner::PrintJobWorkerOwner()
: task_runner_(base::MessageLoop::current()->task_runner()) {
}
: task_runner_(base::ThreadTaskRunnerHandle::Get()) {}
PrintJobWorkerOwner::~PrintJobWorkerOwner() {
}

View file

@ -5,6 +5,8 @@
#ifndef CHROME_BROWSER_PRINTING_PRINT_JOB_WORKER_OWNER_H__
#define CHROME_BROWSER_PRINTING_PRINT_JOB_WORKER_OWNER_H__
#include <memory>
#include "base/memory/ref_counted.h"
#include "printing/printing_context.h"
@ -34,7 +36,8 @@ class PrintJobWorkerOwner
PrintingContext::Result result) = 0;
// Detach the PrintJobWorker associated to this object.
virtual PrintJobWorker* DetachWorker(PrintJobWorkerOwner* new_owner) = 0;
virtual std::unique_ptr<PrintJobWorker> DetachWorker(
PrintJobWorkerOwner* new_owner) = 0;
// Access the current settings.
virtual const PrintSettings& settings() const = 0;

View file

@ -11,6 +11,7 @@
#include "chrome/browser/printing/printer_query.h"
#include "chrome/common/print_messages.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "printing/page_size_margins.h"
@ -97,7 +98,8 @@ void PrintPreviewMessageHandler::OnPrintPreviewFailed(int document_cookie,
}
bool PrintPreviewMessageHandler::OnMessageReceived(
const IPC::Message& message) {
const IPC::Message& message,
content::RenderFrameHost* render_frame_host) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(PrintPreviewMessageHandler, message)
IPC_MESSAGE_HANDLER(PrintHostMsg_MetafileReadyForPrinting,
@ -116,8 +118,8 @@ void PrintPreviewMessageHandler::PrintToPDF(
options.GetInteger(printing::kPreviewRequestID, &request_id);
print_to_pdf_callback_map_[request_id] = callback;
content::RenderViewHost* rvh = web_contents()->GetRenderViewHost();
rvh->Send(new PrintMsg_PrintPreview(rvh->GetRoutingID(), options));
content::RenderFrameHost* rfh = web_contents()->GetMainFrame();
rfh->Send(new PrintMsg_PrintPreview(rfh->GetRoutingID(), options));
}
void PrintPreviewMessageHandler::RunPrintToPDFCallback(

View file

@ -30,7 +30,8 @@ class PrintPreviewMessageHandler
~PrintPreviewMessageHandler() override;
// content::WebContentsObserver implementation.
bool OnMessageReceived(const IPC::Message& message) override;
bool OnMessageReceived(const IPC::Message& message,
content::RenderFrameHost* render_frame_host) override;
void PrintToPDF(const base::DictionaryValue& options,
const atom::api::WebContents::PrintToPDFCallback& callback);

View file

@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/memory/ref_counted_memory.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/timer/timer.h"
@ -25,6 +26,7 @@
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "printing/pdf_metafile_skia.h"
@ -64,10 +66,13 @@ PrintViewManagerBase::~PrintViewManagerBase() {
}
#if !defined(DISABLE_BASIC_PRINTING)
bool PrintViewManagerBase::PrintNow(bool silent, bool print_background,
bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh,
bool silent, bool print_background,
const base::string16& device_name) {
return PrintNowInternal(new PrintMsg_PrintPages(
routing_id(), silent, print_background, device_name));
int32_t id = rfh->GetRoutingID();
return PrintNowInternal(
rfh,
base::MakeUnique<PrintMsg_PrintPages>(id, silent, print_background, device_name));
}
#endif // !DISABLE_BASIC_PRINTING
@ -156,13 +161,18 @@ void PrintViewManagerBase::OnDidPrintPage(
ShouldQuitFromInnerMessageLoop();
#else
if (metafile_must_be_valid) {
bool print_text_with_gdi =
document->settings().print_text_with_gdi() &&
!document->settings().printer_is_xps();
scoped_refptr<base::RefCountedBytes> bytes = new base::RefCountedBytes(
reinterpret_cast<const unsigned char*>(shared_buf.memory()),
params.data_size);
document->DebugDumpData(bytes.get(), FILE_PATH_LITERAL(".pdf"));
print_job_->StartPdfToEmfConversion(
bytes, params.page_size, params.content_area);
bytes, params.page_size, params.content_area,
print_text_with_gdi);
}
#endif // !OS_WIN
}
@ -185,7 +195,9 @@ void PrintViewManagerBase::OnShowInvalidPrinterSettingsError() {
LOG(ERROR) << "Invalid printer settings";
}
bool PrintViewManagerBase::OnMessageReceived(const IPC::Message& message) {
bool PrintViewManagerBase::OnMessageReceived(
const IPC::Message& message,
content::RenderFrameHost* render_frame_host) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(PrintViewManagerBase, message)
IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPrintedPagesCount,
@ -468,13 +480,13 @@ bool PrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) {
return true;
}
bool PrintViewManagerBase::PrintNowInternal(IPC::Message* message) {
// Don't print / print preview interstitials.
if (web_contents()->ShowingInterstitialPage()) {
delete message;
bool PrintViewManagerBase::PrintNowInternal(
content::RenderFrameHost* rfh,
std::unique_ptr<IPC::Message> message) {
// Don't print / print preview interstitials or crashed tabs.
if (web_contents()->ShowingInterstitialPage() || web_contents()->IsCrashed())
return false;
}
return Send(message);
return rfh->Send(message.release());
}
void PrintViewManagerBase::ReleasePrinterQuery() {

View file

@ -39,7 +39,9 @@ class PrintViewManagerBase : public content::NotificationObserver,
// Prints the current document immediately. Since the rendering is
// asynchronous, the actual printing will not be completed on the return of
// this function. Returns false if printing is impossible at the moment.
virtual bool PrintNow(bool silent, bool print_background, const base::string16&);
virtual bool PrintNow(content::RenderFrameHost* rfh,
bool silent, bool print_background,
const base::string16&);
#endif // !DISABLE_BASIC_PRINTING
// PrintedPagesSource implementation.
@ -49,13 +51,15 @@ class PrintViewManagerBase : public content::NotificationObserver,
explicit PrintViewManagerBase(content::WebContents* web_contents);
// Helper method for Print*Now().
bool PrintNowInternal(IPC::Message* message);
bool PrintNowInternal(content::RenderFrameHost* rfh,
std::unique_ptr<IPC::Message> message);
// Terminates or cancels the print job if one was pending.
virtual void RenderProcessGone(base::TerminationStatus status) override;
void RenderProcessGone(base::TerminationStatus status) override;
// content::WebContentsObserver implementation.
virtual bool OnMessageReceived(const IPC::Message& message) override;
bool OnMessageReceived(const IPC::Message& message,
content::RenderFrameHost* render_frame_host) override;
// IPC Message handlers.
virtual void OnPrintingFailed(int cookie);

View file

@ -4,6 +4,9 @@
#include "chrome/browser/printing/printer_query.h"
#include <memory>
#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/message_loop/message_loop.h"
@ -13,8 +16,8 @@
namespace printing {
PrinterQuery::PrinterQuery(int render_process_id, int render_view_id)
: worker_(new PrintJobWorker(render_process_id, render_view_id, this)),
PrinterQuery::PrinterQuery(int render_process_id, int render_frame_id)
: worker_(new PrintJobWorker(render_process_id, render_frame_id, this)),
is_print_dialog_box_shown_(false),
cookie_(PrintSettings::NewCookie()),
last_status_(PrintingContext::FAILED) {
@ -25,7 +28,7 @@ PrinterQuery::~PrinterQuery() {
// The job should be finished (or at least canceled) when it is destroyed.
DCHECK(!is_print_dialog_box_shown_);
// If this fires, it is that this pending printer context has leaked.
DCHECK(!worker_.get());
DCHECK(!worker_);
}
void PrinterQuery::GetSettingsDone(const PrintSettings& new_settings,
@ -47,12 +50,13 @@ void PrinterQuery::GetSettingsDone(const PrintSettings& new_settings,
}
}
PrintJobWorker* PrinterQuery::DetachWorker(PrintJobWorkerOwner* new_owner) {
std::unique_ptr<PrintJobWorker> PrinterQuery::DetachWorker(
PrintJobWorkerOwner* new_owner) {
DCHECK(callback_.is_null());
DCHECK(worker_.get());
DCHECK(worker_);
worker_->SetNewOwner(new_owner);
return worker_.release();
return std::move(worker_);
}
const PrintSettings& PrinterQuery::settings() const {
@ -63,27 +67,26 @@ int PrinterQuery::cookie() const {
return cookie_;
}
void PrinterQuery::GetSettings(
GetSettingsAskParam ask_user_for_settings,
int expected_page_count,
bool has_selection,
MarginType margin_type,
const base::Closure& callback) {
void PrinterQuery::GetSettings(GetSettingsAskParam ask_user_for_settings,
int expected_page_count,
bool has_selection,
MarginType margin_type,
bool is_scripted,
bool is_modifiable,
const base::Closure& callback) {
DCHECK(RunsTasksOnCurrentThread());
DCHECK(!is_print_dialog_box_shown_);
DCHECK(!is_print_dialog_box_shown_ || !is_scripted);
StartWorker(callback);
// Real work is done in PrintJobWorker::GetSettings().
is_print_dialog_box_shown_ = ask_user_for_settings == ASK_USER;
worker_->PostTask(FROM_HERE,
base::Bind(&PrintJobWorker::GetSettings,
base::Unretained(worker_.get()),
is_print_dialog_box_shown_,
expected_page_count,
has_selection,
margin_type,
base::string16()));
is_print_dialog_box_shown_ =
ask_user_for_settings == GetSettingsAskParam::ASK_USER;
worker_->PostTask(
FROM_HERE,
base::Bind(&PrintJobWorker::GetSettings, base::Unretained(worker_.get()),
is_print_dialog_box_shown_, expected_page_count, has_selection,
margin_type, is_scripted, is_modifiable, base::string16()));
}
void PrinterQuery::GetSettings(
@ -91,6 +94,8 @@ void PrinterQuery::GetSettings(
int expected_page_count,
bool has_selection,
MarginType margin_type,
bool is_scripted,
bool is_modifiable,
const base::string16& device_name,
const base::Closure& callback) {
DCHECK(RunsTasksOnCurrentThread());
@ -109,8 +114,9 @@ void PrinterQuery::GetSettings(
device_name));
}
void PrinterQuery::SetSettings(std::unique_ptr<base::DictionaryValue> new_settings,
const base::Closure& callback) {
void PrinterQuery::SetSettings(
std::unique_ptr<base::DictionaryValue> new_settings,
const base::Closure& callback) {
StartWorker(callback);
worker_->PostTask(FROM_HERE,
@ -121,7 +127,7 @@ void PrinterQuery::SetSettings(std::unique_ptr<base::DictionaryValue> new_settin
void PrinterQuery::StartWorker(const base::Closure& callback) {
DCHECK(callback_.is_null());
DCHECK(worker_.get());
DCHECK(worker_);
// Lazily create the worker thread. There is one worker thread per print job.
if (!worker_->IsRunning())
@ -131,7 +137,7 @@ void PrinterQuery::StartWorker(const base::Closure& callback) {
}
void PrinterQuery::StopWorker() {
if (worker_.get()) {
if (worker_) {
// http://crbug.com/66082: We're blocking on the PrinterQuery's worker
// thread. It's not clear to me if this may result in blocking the current
// thread for an unacceptable time. We should probably fix it.
@ -146,7 +152,7 @@ bool PrinterQuery::is_callback_pending() const {
}
bool PrinterQuery::is_valid() const {
return worker_.get() != NULL;
return !!worker_;
}
} // namespace printing

View file

@ -9,6 +9,7 @@
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "chrome/browser/printing/print_job_worker_owner.h"
#include "printing/print_job_constants.h"
@ -25,30 +26,32 @@ class PrintJobWorker;
class PrinterQuery : public PrintJobWorkerOwner {
public:
// GetSettings() UI parameter.
enum GetSettingsAskParam {
enum class GetSettingsAskParam {
DEFAULTS,
ASK_USER,
};
PrinterQuery(int render_process_id, int render_view_id);
PrinterQuery(int render_process_id, int render_frame_id);
// PrintJobWorkerOwner implementation.
virtual void GetSettingsDone(const PrintSettings& new_settings,
PrintingContext::Result result) override;
virtual PrintJobWorker* DetachWorker(PrintJobWorkerOwner* new_owner) override;
virtual const PrintSettings& settings() const override;
virtual int cookie() const override;
void GetSettingsDone(const PrintSettings& new_settings,
PrintingContext::Result result) override;
std::unique_ptr<PrintJobWorker> DetachWorker(
PrintJobWorkerOwner* new_owner) override;
const PrintSettings& settings() const override;
int cookie() const override;
// Initializes the printing context. It is fine to call this function multiple
// times to reinitialize the settings. |web_contents_observer| can be queried
// to find the owner of the print setting dialog box. It is unused when
// |ask_for_user_settings| is DEFAULTS.
void GetSettings(
GetSettingsAskParam ask_user_for_settings,
int expected_page_count,
bool has_selection,
MarginType margin_type,
const base::Closure& callback);
void GetSettings(GetSettingsAskParam ask_user_for_settings,
int expected_page_count,
bool has_selection,
MarginType margin_type,
bool is_scripted,
bool is_modifiable,
const base::Closure& callback);
void GetSettings(
GetSettingsAskParam ask_user_for_settings,
@ -74,7 +77,7 @@ class PrinterQuery : public PrintJobWorkerOwner {
bool is_valid() const;
private:
virtual ~PrinterQuery();
~PrinterQuery() override;
// Lazy create the worker thread. There is one worker thread per print job.
void StartWorker(const base::Closure& callback);

View file

@ -14,23 +14,12 @@
#include "chrome/browser/profiles/profile_io_data.h"
#include "chrome/common/print_messages.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/child_process_host.h"
#include "printing/features/features.h"
#if defined(ENABLE_FULL_PRINTING)
#include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
#endif
#if defined(OS_CHROMEOS)
#include <fcntl.h>
#include <map>
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "chrome/browser/printing/print_dialog_cloud.h"
#endif
#if defined(OS_ANDROID)
#include "base/strings/string_number_conversions.h"
@ -44,19 +33,6 @@ namespace printing {
namespace {
#if defined(OS_CHROMEOS)
typedef std::map<int, base::FilePath> SequenceToPathMap;
struct PrintingSequencePathMap {
SequenceToPathMap map;
int sequence;
};
// No locking, only access on the FILE thread.
static base::LazyInstance<PrintingSequencePathMap>
g_printing_file_descriptor_map = LAZY_INSTANCE_INITIALIZER;
#endif
void RenderParamsFromPrintSettings(const PrintSettings& settings,
PrintMsg_Print_Params* params) {
params->page_size = settings.page_setup_device_units().physical_size();
@ -71,6 +47,7 @@ void RenderParamsFromPrintSettings(const PrintSettings& settings,
params->margin_top = settings.page_setup_device_units().content_area().y();
params->margin_left = settings.page_setup_device_units().content_area().x();
params->dpi = settings.dpi();
params->scale_factor = settings.scale_factor();
// Currently hardcoded at 72dpi. See PrintSettings' constructor.
params->desired_dpi = settings.desired_dpi();
// Always use an invalid cookie.
@ -78,10 +55,30 @@ void RenderParamsFromPrintSettings(const PrintSettings& settings,
params->selection_only = settings.selection_only();
params->supports_alpha_blend = settings.supports_alpha_blend();
params->should_print_backgrounds = settings.should_print_backgrounds();
params->display_header_footer = settings.display_header_footer();
params->title = settings.title();
params->url = settings.url();
}
#if defined(OS_ANDROID)
content::WebContents* GetWebContentsForRenderFrame(int render_process_id,
int render_frame_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
content::RenderFrameHost* frame =
content::RenderFrameHost::FromID(render_process_id, render_frame_id);
return frame ? content::WebContents::FromRenderFrameHost(frame) : nullptr;
}
PrintViewManagerBasic* GetPrintManager(int render_process_id,
int render_frame_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
content::WebContents* web_contents =
GetWebContentsForRenderFrame(render_process_id, render_frame_id);
return web_contents ? PrintViewManagerBasic::FromWebContents(web_contents)
: nullptr;
}
#endif
} // namespace
PrintingMessageFilter::PrintingMessageFilter(int render_process_id)
@ -94,14 +91,13 @@ PrintingMessageFilter::PrintingMessageFilter(int render_process_id)
PrintingMessageFilter::~PrintingMessageFilter() {
}
void PrintingMessageFilter::OnDestruct() const {
BrowserThread::DeleteOnUIThread::Destruct(this);
}
void PrintingMessageFilter::OverrideThreadForMessage(
const IPC::Message& message, BrowserThread::ID* thread) {
#if defined(OS_CHROMEOS)
if (message.type() == PrintHostMsg_AllocateTempFileForPrinting::ID ||
message.type() == PrintHostMsg_TempFileForPrintingWritten::ID) {
*thread = BrowserThread::FILE;
}
#elif defined(OS_ANDROID)
#if defined(OS_ANDROID)
if (message.type() == PrintHostMsg_AllocateTempFileForPrinting::ID ||
message.type() == PrintHostMsg_TempFileForPrintingWritten::ID) {
*thread = BrowserThread::UI;
@ -112,10 +108,7 @@ void PrintingMessageFilter::OverrideThreadForMessage(
bool PrintingMessageFilter::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(PrintingMessageFilter, message)
#if defined(OS_WIN)
IPC_MESSAGE_HANDLER(PrintHostMsg_DuplicateSection, OnDuplicateSection)
#endif
#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
#if defined(OS_ANDROID)
IPC_MESSAGE_HANDLER(PrintHostMsg_AllocateTempFileForPrinting,
OnAllocateTempFileForPrinting)
IPC_MESSAGE_HANDLER(PrintHostMsg_TempFileForPrintingWritten,
@ -129,139 +122,46 @@ bool PrintingMessageFilter::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_ScriptedPrint, OnScriptedPrint)
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_UpdatePrintSettings,
OnUpdatePrintSettings)
#if defined(ENABLE_FULL_PRINTING)
IPC_MESSAGE_HANDLER(PrintHostMsg_CheckForCancel, OnCheckForCancel)
#endif
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
#if defined(OS_WIN)
void PrintingMessageFilter::OnDuplicateSection(
base::SharedMemoryHandle renderer_handle,
base::SharedMemoryHandle* browser_handle) {
// Duplicate the handle in this process right now so the memory is kept alive
// (even if it is not mapped)
base::SharedMemory shared_buf(renderer_handle, true);
shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), browser_handle);
}
#endif
#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
#if defined(OS_ANDROID)
void PrintingMessageFilter::OnAllocateTempFileForPrinting(
int render_view_id,
int render_frame_id,
base::FileDescriptor* temp_file_fd,
int* sequence_number) {
#if defined(OS_CHROMEOS)
// TODO(thestig): Use |render_view_id| for Chrome OS.
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
temp_file_fd->fd = *sequence_number = -1;
temp_file_fd->auto_close = false;
SequenceToPathMap* map = &g_printing_file_descriptor_map.Get().map;
*sequence_number = g_printing_file_descriptor_map.Get().sequence++;
base::FilePath path;
if (base::CreateTemporaryFile(&path)) {
int fd = open(path.value().c_str(), O_WRONLY);
if (fd >= 0) {
SequenceToPathMap::iterator it = map->find(*sequence_number);
if (it != map->end()) {
NOTREACHED() << "Sequence number already in use. seq=" <<
*sequence_number;
} else {
(*map)[*sequence_number] = path;
temp_file_fd->fd = fd;
temp_file_fd->auto_close = true;
}
}
}
#elif defined(OS_ANDROID)
DCHECK_CURRENTLY_ON(BrowserThread::UI);
content::WebContents* wc = GetWebContentsForRenderView(render_view_id);
if (!wc)
return;
PrintViewManagerBasic* print_view_manager =
PrintViewManagerBasic::FromWebContents(wc);
GetPrintManager(render_process_id_, render_frame_id);
if (!print_view_manager)
return;
// The file descriptor is originally created in & passed from the Android
// side, and it will handle the closing.
const base::FileDescriptor& file_descriptor =
print_view_manager->file_descriptor();
temp_file_fd->fd = file_descriptor.fd;
temp_file_fd->fd = print_view_manager->file_descriptor().fd;
temp_file_fd->auto_close = false;
#endif
}
void PrintingMessageFilter::OnTempFileForPrintingWritten(int render_view_id,
void PrintingMessageFilter::OnTempFileForPrintingWritten(int render_frame_id,
int sequence_number) {
#if defined(OS_CHROMEOS)
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
SequenceToPathMap* map = &g_printing_file_descriptor_map.Get().map;
SequenceToPathMap::iterator it = map->find(sequence_number);
if (it == map->end()) {
NOTREACHED() << "Got a sequence that we didn't pass to the "
"renderer: " << sequence_number;
return;
}
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&PrintingMessageFilter::CreatePrintDialogForFile,
this, render_view_id, it->second));
// Erase the entry in the map.
map->erase(it);
#elif defined(OS_ANDROID)
DCHECK_CURRENTLY_ON(BrowserThread::UI);
content::WebContents* wc = GetWebContentsForRenderView(render_view_id);
if (!wc)
return;
PrintViewManagerBasic* print_view_manager =
PrintViewManagerBasic::FromWebContents(wc);
const base::FileDescriptor& file_descriptor =
print_view_manager->file_descriptor();
PrintingContextAndroid::PdfWritingDone(file_descriptor.fd, true);
// Invalidate the file descriptor so it doesn't accidentally get reused.
print_view_manager->set_file_descriptor(base::FileDescriptor(-1, false));
#endif
}
#endif // defined(OS_CHROMEOS) || defined(OS_ANDROID)
#if defined(OS_CHROMEOS)
void PrintingMessageFilter::CreatePrintDialogForFile(
int render_view_id,
const base::FilePath& path) {
content::WebContents* wc = GetWebContentsForRenderView(render_view_id);
if (!wc)
return;
print_dialog_cloud::CreatePrintDialogForFile(
wc->GetBrowserContext(),
wc->GetTopLevelNativeWindow(),
path,
wc->GetTitle(),
base::string16(),
std::string("application/pdf"));
}
#endif // defined(OS_CHROMEOS)
content::WebContents* PrintingMessageFilter::GetWebContentsForRenderView(
int render_view_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
content::RenderViewHost* view = content::RenderViewHost::FromID(
render_process_id_, render_view_id);
return view ? content::WebContents::FromRenderViewHost(view) : NULL;
GetPrintManager(render_process_id_, render_frame_id);
if (print_view_manager)
print_view_manager->PdfWritingDone(true);
}
#endif // defined(OS_ANDROID)
void PrintingMessageFilter::OnGetDefaultPrintSettings(IPC::Message* reply_msg) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
scoped_refptr<PrinterQuery> printer_query;
#if 0
if (!profile_io_data_->printing_enabled()->GetValue()) {
if (false) {
// Reply with NULL query.
OnGetDefaultPrintSettingsReply(printer_query, reply_msg);
return;
}
#endif
printer_query = queue_->PopPrinterQuery(0);
if (!printer_query.get()) {
printer_query =
@ -271,14 +171,10 @@ void PrintingMessageFilter::OnGetDefaultPrintSettings(IPC::Message* reply_msg) {
// Loads default settings. This is asynchronous, only the IPC message sender
// will hang until the settings are retrieved.
printer_query->GetSettings(
PrinterQuery::DEFAULTS,
0,
false,
DEFAULT_MARGINS,
base::Bind(&PrintingMessageFilter::OnGetDefaultPrintSettingsReply,
this,
printer_query,
reply_msg));
PrinterQuery::GetSettingsAskParam::DEFAULTS, 0, false, DEFAULT_MARGINS,
false, false,
base::Bind(&PrintingMessageFilter::OnGetDefaultPrintSettingsReply, this,
printer_query, reply_msg));
}
void PrintingMessageFilter::OnInitSettingWithDeviceName(const base::string16& device_name,
@ -339,14 +235,10 @@ void PrintingMessageFilter::OnScriptedPrint(
queue_->CreatePrinterQuery(render_process_id_, reply_msg->routing_id());
}
printer_query->GetSettings(
PrinterQuery::ASK_USER,
params.expected_pages_count,
params.has_selection,
params.margin_type,
base::Bind(&PrintingMessageFilter::OnScriptedPrintReply,
this,
printer_query,
reply_msg));
PrinterQuery::GetSettingsAskParam::ASK_USER, params.expected_pages_count,
params.has_selection, params.margin_type, true, true,
base::Bind(&PrintingMessageFilter::OnScriptedPrintReply, this,
printer_query, reply_msg));
}
void PrintingMessageFilter::OnScriptedPrintReply(
@ -434,11 +326,10 @@ void PrintingMessageFilter::OnUpdatePrintSettingsReply(
params.params.document_cookie = printer_query->cookie();
params.pages = PageRange::GetPages(printer_query->settings().ranges());
}
PrintHostMsg_UpdatePrintSettings::WriteReplyParams(
reply_msg,
params,
printer_query.get() &&
(printer_query->last_status() == printing::PrintingContext::CANCEL));
bool canceled = printer_query.get() &&
(printer_query->last_status() == PrintingContext::CANCEL);
PrintHostMsg_UpdatePrintSettings::WriteReplyParams(reply_msg, params,
canceled);
Send(reply_msg);
// If user hasn't cancelled.
if (printer_query.get()) {

View file

@ -10,13 +10,7 @@
#include "base/compiler_specific.h"
#include "content/public/browser/browser_message_filter.h"
#if defined(OS_WIN)
#include "base/memory/shared_memory.h"
#endif
struct PrintHostMsg_ScriptedPrint_Params;
class Profile;
class ProfileIOData;
namespace base {
class DictionaryValue;
@ -29,7 +23,6 @@ class WebContents;
namespace printing {
class PrintJobManager;
class PrintQueriesQueue;
class PrinterQuery;
@ -46,43 +39,26 @@ class PrintingMessageFilter : public content::BrowserMessageFilter {
bool OnMessageReceived(const IPC::Message& message) override;
private:
friend class base::DeleteHelper<PrintingMessageFilter>;
friend class content::BrowserThread;
virtual ~PrintingMessageFilter();
#if defined(OS_WIN)
// Used to pass resulting EMF from renderer to browser in printing.
void OnDuplicateSection(base::SharedMemoryHandle renderer_handle,
base::SharedMemoryHandle* browser_handle);
#endif
#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
// Used to ask the browser allocate a temporary file for the renderer
// to fill in resulting PDF in renderer.
void OnAllocateTempFileForPrinting(int render_view_id,
base::FileDescriptor* temp_file_fd,
int* sequence_number);
void OnTempFileForPrintingWritten(int render_view_id, int sequence_number);
#endif
#if defined(OS_CHROMEOS)
void CreatePrintDialogForFile(int render_view_id, const base::FilePath& path);
#endif
void OnDestruct() const override;
#if defined(OS_ANDROID)
// Used to ask the browser allocate a temporary file for the renderer
// to fill in resulting PDF in renderer.
void OnAllocateTempFileForPrinting(int render_frame_id,
base::FileDescriptor* temp_file_fd,
int* sequence_number);
void OnTempFileForPrintingWritten(int render_frame_id, int sequence_number);
// Updates the file descriptor for the PrintViewManagerBasic of a given
// render_view_id.
void UpdateFileDescriptor(int render_view_id, int fd);
// render_frame_id.
void UpdateFileDescriptor(int render_frame_id, int fd);
#endif
// Given a render_view_id get the corresponding WebContents.
// Must be called on the UI thread.
content::WebContents* GetWebContentsForRenderView(int render_view_id);
// GetPrintSettingsForRenderView must be called via PostTask and
// base::Bind. Collapse the settings-specific params into a
// struct to avoid running into issues with too many params
// to base::Bind.
struct GetPrintSettingsForRenderViewParams;
// Get the default print setting.
void OnGetDefaultPrintSettings(IPC::Message* reply_msg);
@ -110,13 +86,6 @@ class PrintingMessageFilter : public content::BrowserMessageFilter {
void OnUpdatePrintSettingsReply(scoped_refptr<PrinterQuery> printer_query,
IPC::Message* reply_msg);
#if defined(ENABLE_FULL_PRINTING)
// Check to see if print preview has been cancelled.
void OnCheckForCancel(int32_t preview_ui_id,
int preview_request_id,
bool* cancel);
#endif
const int render_process_id_;
scoped_refptr<PrintQueriesQueue> queue_;

View file

@ -985,16 +985,16 @@ bool ProcessSingleton::Create() {
// Check that the directory was created with the correct permissions.
int dir_mode = 0;
CHECK(base::GetPosixFilePermissions(socket_dir_.path(), &dir_mode) &&
CHECK(base::GetPosixFilePermissions(socket_dir_.GetPath(), &dir_mode) &&
dir_mode == base::FILE_PERMISSION_USER_MASK)
<< "Temp directory mode is not 700: " << std::oct << dir_mode;
// Setup the socket symlink and the two cookies.
base::FilePath socket_target_path =
socket_dir_.path().Append(kSingletonSocketFilename);
socket_dir_.GetPath().Append(kSingletonSocketFilename);
base::FilePath cookie(GenerateCookie());
base::FilePath remote_cookie_path =
socket_dir_.path().Append(kSingletonCookieFilename);
socket_dir_.GetPath().Append(kSingletonCookieFilename);
UnlinkPath(socket_path_);
UnlinkPath(cookie_path_);
if (!SymlinkPath(socket_target_path, socket_path_) ||

View file

@ -24,7 +24,7 @@ WidevineCdmMessageFilter::WidevineCdmMessageFilter(
bool WidevineCdmMessageFilter::OnMessageReceived(const IPC::Message& message) {
IPC_BEGIN_MESSAGE_MAP(WidevineCdmMessageFilter, message)
#if defined(ENABLE_PEPPER_CDMS)
#if BUILDFLAG(ENABLE_PEPPER_CDMS)
IPC_MESSAGE_HANDLER(
ChromeViewHostMsg_IsInternalPluginAvailableForMimeType,
OnIsInternalPluginAvailableForMimeType)
@ -34,7 +34,7 @@ bool WidevineCdmMessageFilter::OnMessageReceived(const IPC::Message& message) {
return true;
}
#if defined(ENABLE_PEPPER_CDMS)
#if BUILDFLAG(ENABLE_PEPPER_CDMS)
void WidevineCdmMessageFilter::OnIsInternalPluginAvailableForMimeType(
const std::string& mime_type,
bool* is_available,
@ -60,7 +60,7 @@ void WidevineCdmMessageFilter::OnIsInternalPluginAvailableForMimeType(
*is_available = false;
}
#endif // defined(ENABLE_PEPPER_CDMS)
#endif // BUILDFLAG(ENABLE_PEPPER_CDMS)
void WidevineCdmMessageFilter::OnDestruct() const {
BrowserThread::DeleteOnUIThread::Destruct(this);

View file

@ -25,7 +25,7 @@ class WidevineCdmMessageFilter : public content::BrowserMessageFilter {
virtual ~WidevineCdmMessageFilter();
#if defined(ENABLE_PEPPER_CDMS)
#if BUILDFLAG(ENABLE_PEPPER_CDMS)
// Returns whether any internal plugin supporting |mime_type| is registered
// and enabled. Does not determine whether the plugin can actually be
// instantiated (e.g. whether it has all its dependencies).

View file

@ -0,0 +1,215 @@
// Copyright 2015 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 "chrome/browser/ssl/security_state_tab_helper.h"
#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
#include "build/build_config.h"
#if 0
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/policy/policy_cert_service.h"
#include "chrome/browser/chromeos/policy/policy_cert_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "chrome/browser/safe_browsing/ui_manager.h"
#endif
#include "components/prefs/pref_service.h"
#include "components/security_state/content/content_utils.h"
#if 0
#include "components/ssl_config/ssl_config_prefs.h"
#endif
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/origin_util.h"
#include "net/base/net_errors.h"
#include "net/cert/x509_certificate.h"
#include "net/ssl/ssl_cipher_suite_names.h"
#include "net/ssl/ssl_connection_status_flags.h"
#include "third_party/boringssl/src/include/openssl/ssl.h"
#include "ui/base/l10n/l10n_util.h"
DEFINE_WEB_CONTENTS_USER_DATA_KEY(SecurityStateTabHelper);
#if 0
using safe_browsing::SafeBrowsingUIManager;
#endif
SecurityStateTabHelper::SecurityStateTabHelper(
content::WebContents* web_contents)
: content::WebContentsObserver(web_contents),
logged_http_warning_on_current_navigation_(false) {}
SecurityStateTabHelper::~SecurityStateTabHelper() {}
void SecurityStateTabHelper::GetSecurityInfo(
security_state::SecurityInfo* result) const {
security_state::GetSecurityInfo(GetVisibleSecurityState(),
UsedPolicyInstalledCertificate(),
base::Bind(&content::IsOriginSecure), result);
}
void SecurityStateTabHelper::VisibleSecurityStateChanged() {
if (logged_http_warning_on_current_navigation_)
return;
security_state::SecurityInfo security_info;
GetSecurityInfo(&security_info);
if (!security_info.displayed_password_field_on_http &&
!security_info.displayed_credit_card_field_on_http) {
return;
}
DCHECK(time_of_http_warning_on_current_navigation_.is_null());
time_of_http_warning_on_current_navigation_ = base::Time::Now();
std::string warning;
bool warning_is_user_visible = false;
switch (security_info.security_level) {
case security_state::HTTP_SHOW_WARNING:
warning =
"This page includes a password or credit card input in a non-secure "
"context. A warning has been added to the URL bar. For more "
"information, see https://goo.gl/zmWq3m.";
warning_is_user_visible = true;
break;
case security_state::NONE:
case security_state::DANGEROUS:
warning =
"This page includes a password or credit card input in a non-secure "
"context. A warning will be added to the URL bar in Chrome 56 (Jan "
"2017). For more information, see https://goo.gl/zmWq3m.";
break;
default:
return;
}
logged_http_warning_on_current_navigation_ = true;
web_contents()->GetMainFrame()->AddMessageToConsole(
content::CONSOLE_MESSAGE_LEVEL_WARNING, warning);
if (security_info.displayed_credit_card_field_on_http) {
UMA_HISTOGRAM_BOOLEAN(
"Security.HTTPBad.UserWarnedAboutSensitiveInput.CreditCard",
warning_is_user_visible);
}
if (security_info.displayed_password_field_on_http) {
UMA_HISTOGRAM_BOOLEAN(
"Security.HTTPBad.UserWarnedAboutSensitiveInput.Password",
warning_is_user_visible);
}
}
void SecurityStateTabHelper::DidStartNavigation(
content::NavigationHandle* navigation_handle) {
if (time_of_http_warning_on_current_navigation_.is_null() ||
!navigation_handle->IsInMainFrame() || navigation_handle->IsSamePage()) {
return;
}
// Record how quickly a user leaves a site after encountering an
// HTTP-bad warning. A navigation here only counts if it is a
// main-frame, not-same-page navigation, since it aims to measure how
// quickly a user leaves a site after seeing the HTTP warning.
UMA_HISTOGRAM_LONG_TIMES(
"Security.HTTPBad.NavigationStartedAfterUserWarnedAboutSensitiveInput",
base::Time::Now() - time_of_http_warning_on_current_navigation_);
// After recording the histogram, clear the time of the warning. A
// timing histogram will not be recorded again on this page, because
// the time is only set the first time the HTTP-bad warning is shown
// per page.
time_of_http_warning_on_current_navigation_ = base::Time();
}
void SecurityStateTabHelper::DidFinishNavigation(
content::NavigationHandle* navigation_handle) {
if (navigation_handle->IsInMainFrame() && !navigation_handle->IsSamePage()) {
// Only reset the console message flag for main-frame navigations,
// and not for same-page navigations like reference fragments and pushState.
logged_http_warning_on_current_navigation_ = false;
}
}
void SecurityStateTabHelper::WebContentsDestroyed() {
if (time_of_http_warning_on_current_navigation_.is_null()) {
return;
}
// Record how quickly the tab is closed after a user encounters an
// HTTP-bad warning. This histogram will only be recorded if the
// WebContents is destroyed before another navigation begins.
UMA_HISTOGRAM_LONG_TIMES(
"Security.HTTPBad.WebContentsDestroyedAfterUserWarnedAboutSensitiveInput",
base::Time::Now() - time_of_http_warning_on_current_navigation_);
}
bool SecurityStateTabHelper::UsedPolicyInstalledCertificate() const {
#if defined(OS_CHROMEOS)
policy::PolicyCertService* service =
policy::PolicyCertServiceFactory::GetForProfile(
Profile::FromBrowserContext(web_contents()->GetBrowserContext()));
if (service && service->UsedPolicyCertificates())
return true;
#endif
return false;
}
#if 0
security_state::MaliciousContentStatus
SecurityStateTabHelper::GetMaliciousContentStatus() const {
content::NavigationEntry* entry =
web_contents()->GetController().GetVisibleEntry();
if (!entry)
return security_state::MALICIOUS_CONTENT_STATUS_NONE;
safe_browsing::SafeBrowsingService* sb_service =
g_browser_process->safe_browsing_service();
if (!sb_service)
return security_state::MALICIOUS_CONTENT_STATUS_NONE;
scoped_refptr<SafeBrowsingUIManager> sb_ui_manager = sb_service->ui_manager();
safe_browsing::SBThreatType threat_type;
if (sb_ui_manager->IsUrlWhitelistedOrPendingForWebContents(
entry->GetURL(), false, entry, web_contents(), false, &threat_type)) {
switch (threat_type) {
case safe_browsing::SB_THREAT_TYPE_UNUSED:
case safe_browsing::SB_THREAT_TYPE_SAFE:
break;
case safe_browsing::SB_THREAT_TYPE_URL_PHISHING:
case safe_browsing::SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL:
return security_state::MALICIOUS_CONTENT_STATUS_SOCIAL_ENGINEERING;
break;
case safe_browsing::SB_THREAT_TYPE_URL_MALWARE:
case safe_browsing::SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL:
return security_state::MALICIOUS_CONTENT_STATUS_MALWARE;
break;
case safe_browsing::SB_THREAT_TYPE_URL_UNWANTED:
return security_state::MALICIOUS_CONTENT_STATUS_UNWANTED_SOFTWARE;
break;
case safe_browsing::SB_THREAT_TYPE_BINARY_MALWARE_URL:
case safe_browsing::SB_THREAT_TYPE_EXTENSION:
case safe_browsing::SB_THREAT_TYPE_BLACKLISTED_RESOURCE:
case safe_browsing::SB_THREAT_TYPE_API_ABUSE:
// These threat types are not currently associated with
// interstitials, and thus resources with these threat types are
// not ever whitelisted or pending whitelisting.
NOTREACHED();
break;
}
}
return security_state::MALICIOUS_CONTENT_STATUS_NONE;
}
#endif
std::unique_ptr<security_state::VisibleSecurityState>
SecurityStateTabHelper::GetVisibleSecurityState() const {
auto state = security_state::GetVisibleSecurityState(web_contents());
#if 0
// Malware status might already be known even if connection security
// information is still being initialized, thus no need to check for that.
state->malicious_content_status = GetMaliciousContentStatus();
#endif
return state;
}

View file

@ -0,0 +1,70 @@
// Copyright 2015 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 CHROME_BROWSER_SSL_SECURITY_STATE_TAB_HELPER_H_
#define CHROME_BROWSER_SSL_SECURITY_STATE_TAB_HELPER_H_
#include <memory>
#include "base/macros.h"
#include "components/security_state/core/security_state.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
#include "third_party/WebKit/public/platform/WebSecurityStyle.h"
namespace content {
class NavigationHandle;
class WebContents;
} // namespace content
// Tab helper provides the page's security status. Also logs console warnings
// for private data on insecure pages.
class SecurityStateTabHelper
: public content::WebContentsObserver,
public content::WebContentsUserData<SecurityStateTabHelper> {
public:
~SecurityStateTabHelper() override;
// See security_state::GetSecurityInfo.
void GetSecurityInfo(
security_state::SecurityInfo* result) const;
// Called when the NavigationEntry's SSLStatus or other security
// information changes.
void VisibleSecurityStateChanged();
// content::WebContentsObserver:
void DidStartNavigation(
content::NavigationHandle* navigation_handle) override;
void DidFinishNavigation(
content::NavigationHandle* navigation_handle) override;
void WebContentsDestroyed() override;
private:
explicit SecurityStateTabHelper(content::WebContents* web_contents);
friend class content::WebContentsUserData<SecurityStateTabHelper>;
bool UsedPolicyInstalledCertificate() const;
#if 0
security_state::MaliciousContentStatus GetMaliciousContentStatus() const;
#endif
std::unique_ptr<security_state::VisibleSecurityState>
GetVisibleSecurityState() const;
// True if a console message has been logged about an omnibox warning that
// will be shown in future versions of Chrome for insecure HTTP pages. This
// message should only be logged once per main-frame navigation.
bool logged_http_warning_on_current_navigation_;
// The time that a console or omnibox warning was shown for insecure
// HTTP pages that contain password or credit card fields. This is set
// at most once per main-frame navigation (the first time that an HTTP
// warning triggers on that navigation) and is used for UMA
// histogramming.
base::Time time_of_http_warning_on_current_navigation_;
DISALLOW_COPY_AND_ASSIGN(SecurityStateTabHelper);
};
#endif // CHROME_BROWSER_SSL_SECURITY_STATE_TAB_HELPER_H_

View file

@ -36,7 +36,7 @@ ColorChooserDialog::ColorChooserDialog(views::ColorChooserListener* listener,
HWND owning_hwnd = views::HWNDForNativeWindow(owning_window);
ExecuteOpenParams execute_params(initial_color, BeginRun(owning_hwnd),
owning_hwnd);
execute_params.run_state.dialog_thread->message_loop()->PostTask(FROM_HERE,
execute_params.run_state.dialog_thread->task_runner()->PostTask(FROM_HERE,
base::Bind(&ColorChooserDialog::ExecuteOpen, this, execute_params));
}