refactor: move printing out of chromium_src (#15023)
* remove printing related things from chromium_src * chore: add printing build flag and patch * fix: include PrintingService on other platforms too * fix: printing_handler is only needed on Windows * fix: format BUILD.gn properly * fix: rename printing build flag to avoid conflict with chromium * fix: place previously missed printing calls behind build flag * fix: accidentally renamed flag in patch file * fix: don't include all printing strings * fix: allow ShowItemInFolder and OpenItem to block, fixing a DCHECK crash * fix: make things compile, some changes got lost while rebasing * fix: remove rogue line from BUILD.gn * chore: update patch description * style: lint fix * chore: use chromium printing buildflag, move node related stuff out of patch * revert: remove ScopedAllowBlockingForTesting call * fix: fix my rebase blooper * fix: re-add header lost during rebase, update patch * fix: add <map> include, tweak the patch a bit * revert: remove rogue diff from patch * fix: clean up after rebase
This commit is contained in:
parent
c806c465fa
commit
a82bcc7e3c
53 changed files with 1398 additions and 7358 deletions
73
BUILD.gn
73
BUILD.gn
|
@ -206,11 +206,11 @@ static_library("electron_lib") {
|
||||||
"native_mate",
|
"native_mate",
|
||||||
"//base",
|
"//base",
|
||||||
"//base:i18n",
|
"//base:i18n",
|
||||||
|
"//chrome/common",
|
||||||
"//components/certificate_transparency",
|
"//components/certificate_transparency",
|
||||||
"//components/net_log",
|
"//components/net_log",
|
||||||
"//components/network_session_configurator/common",
|
"//components/network_session_configurator/common",
|
||||||
"//components/prefs",
|
"//components/prefs",
|
||||||
"//components/printing/common",
|
|
||||||
"//components/viz/service",
|
"//components/viz/service",
|
||||||
"//content/public/app:both",
|
"//content/public/app:both",
|
||||||
"//content/public/child",
|
"//content/public/child",
|
||||||
|
@ -221,7 +221,6 @@ static_library("electron_lib") {
|
||||||
"//ppapi/host",
|
"//ppapi/host",
|
||||||
"//ppapi/proxy",
|
"//ppapi/proxy",
|
||||||
"//ppapi/shared_impl",
|
"//ppapi/shared_impl",
|
||||||
"//printing",
|
|
||||||
"//services/proxy_resolver:lib",
|
"//services/proxy_resolver:lib",
|
||||||
"//skia",
|
"//skia",
|
||||||
"//third_party/blink/public:blink",
|
"//third_party/blink/public:blink",
|
||||||
|
@ -358,10 +357,10 @@ static_library("electron_lib") {
|
||||||
# Disable warnings for g_settings_list_schemas.
|
# Disable warnings for g_settings_list_schemas.
|
||||||
"GLIB_DISABLE_DEPRECATION_WARNINGS",
|
"GLIB_DISABLE_DEPRECATION_WARNINGS",
|
||||||
]
|
]
|
||||||
|
|
||||||
sources += filenames.lib_sources_nss
|
sources += filenames.lib_sources_nss
|
||||||
}
|
}
|
||||||
if (is_win) {
|
if (is_win) {
|
||||||
sources += filenames.lib_sources_win
|
|
||||||
libs += [ "dwmapi.lib" ]
|
libs += [ "dwmapi.lib" ]
|
||||||
}
|
}
|
||||||
if (is_linux || is_win) {
|
if (is_linux || is_win) {
|
||||||
|
@ -428,6 +427,65 @@ static_library("electron_lib") {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (enable_basic_printing) {
|
||||||
|
deps += [
|
||||||
|
"//chrome/common:mojo_bindings",
|
||||||
|
"//chrome/services/printing:lib",
|
||||||
|
"//components/printing/browser",
|
||||||
|
"//components/printing/common",
|
||||||
|
"//components/printing/renderer",
|
||||||
|
"//components/services/pdf_compositor/public/cpp:utils",
|
||||||
|
"//components/services/pdf_compositor/public/interfaces",
|
||||||
|
"//printing",
|
||||||
|
]
|
||||||
|
|
||||||
|
sources += [
|
||||||
|
"//chrome/browser/printing/print_job.cc",
|
||||||
|
"//chrome/browser/printing/print_job.h",
|
||||||
|
"//chrome/browser/printing/print_job_manager.cc",
|
||||||
|
"//chrome/browser/printing/print_job_manager.h",
|
||||||
|
"//chrome/browser/printing/print_job_worker.cc",
|
||||||
|
"//chrome/browser/printing/print_job_worker.h",
|
||||||
|
"//chrome/browser/printing/print_preview_message_handler.cc",
|
||||||
|
"//chrome/browser/printing/print_preview_message_handler.h",
|
||||||
|
"//chrome/browser/printing/print_view_manager_base.cc",
|
||||||
|
"//chrome/browser/printing/print_view_manager_base.h",
|
||||||
|
"//chrome/browser/printing/print_view_manager_basic.cc",
|
||||||
|
"//chrome/browser/printing/print_view_manager_basic.h",
|
||||||
|
"//chrome/browser/printing/print_view_manager_common.cc",
|
||||||
|
"//chrome/browser/printing/print_view_manager_common.h",
|
||||||
|
"//chrome/browser/printing/printer_manager_dialog.h",
|
||||||
|
"//chrome/browser/printing/printer_manager_dialog_linux.cc",
|
||||||
|
"//chrome/browser/printing/printer_manager_dialog_mac.mm",
|
||||||
|
"//chrome/browser/printing/printer_manager_dialog_win.cc",
|
||||||
|
"//chrome/browser/printing/printer_query.cc",
|
||||||
|
"//chrome/browser/printing/printer_query.h",
|
||||||
|
"//chrome/browser/printing/printing_message_filter.cc",
|
||||||
|
"//chrome/browser/printing/printing_message_filter.h",
|
||||||
|
"//chrome/renderer/prerender/prerender_dispatcher.cc",
|
||||||
|
"//chrome/renderer/prerender/prerender_dispatcher.h",
|
||||||
|
"//chrome/renderer/prerender/prerender_extra_data.cc",
|
||||||
|
"//chrome/renderer/prerender/prerender_extra_data.h",
|
||||||
|
"//chrome/renderer/prerender/prerender_helper.cc",
|
||||||
|
"//chrome/renderer/prerender/prerender_helper.h",
|
||||||
|
"//chrome/renderer/prerender/prerenderer_client.cc",
|
||||||
|
"//chrome/renderer/prerender/prerenderer_client.h",
|
||||||
|
"//chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc",
|
||||||
|
"//chrome/renderer/printing/chrome_print_render_frame_helper_delegate.h",
|
||||||
|
"//electron/atom/browser/atom_print_preview_message_handler.cc",
|
||||||
|
"//electron/atom/browser/atom_print_preview_message_handler.h",
|
||||||
|
]
|
||||||
|
|
||||||
|
if (is_win) {
|
||||||
|
sources += [
|
||||||
|
"//chrome/browser/printing/pdf_to_emf_converter.cc",
|
||||||
|
"//chrome/browser/printing/pdf_to_emf_converter.h",
|
||||||
|
"//chrome/utility/printing_handler.cc",
|
||||||
|
"//chrome/utility/printing_handler.h",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (enable_pepper_flash) {
|
if (enable_pepper_flash) {
|
||||||
deps += [ "components/pepper_flash" ]
|
deps += [ "components/pepper_flash" ]
|
||||||
}
|
}
|
||||||
|
@ -770,7 +828,6 @@ group("chromium_unittests") {
|
||||||
"//mojo:mojo_unittests",
|
"//mojo:mojo_unittests",
|
||||||
"//net:net_unittests",
|
"//net:net_unittests",
|
||||||
"//ppapi:ppapi_unittests",
|
"//ppapi:ppapi_unittests",
|
||||||
"//printing:printing_unittests",
|
|
||||||
"//skia:skia_unittests",
|
"//skia:skia_unittests",
|
||||||
"//sql:sql_unittests",
|
"//sql:sql_unittests",
|
||||||
"//storage:storage_unittests",
|
"//storage:storage_unittests",
|
||||||
|
@ -788,6 +845,10 @@ group("chromium_unittests") {
|
||||||
"//v8/test/unittests:unittests",
|
"//v8/test/unittests:unittests",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if (enable_basic_printing) {
|
||||||
|
deps += [ "//printing:printing_unittests" ]
|
||||||
|
}
|
||||||
|
|
||||||
if (is_linux) {
|
if (is_linux) {
|
||||||
deps += [
|
deps += [
|
||||||
"//net:disk_cache_memory_test",
|
"//net:disk_cache_memory_test",
|
||||||
|
@ -929,6 +990,10 @@ group("electron_content_manifest_overlays") {
|
||||||
service_manifest("electron_content_packaged_services_manifest_overlay") {
|
service_manifest("electron_content_packaged_services_manifest_overlay") {
|
||||||
source = "//electron/manifests/electron_content_packaged_services_manifest_overlay.json"
|
source = "//electron/manifests/electron_content_packaged_services_manifest_overlay.json"
|
||||||
packaged_services = [ "//services/proxy_resolver:proxy_resolver_manifest" ]
|
packaged_services = [ "//services/proxy_resolver:proxy_resolver_manifest" ]
|
||||||
|
|
||||||
|
if (enable_basic_printing) {
|
||||||
|
packaged_services += [ "//chrome/services/printing:manifest" ]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
service_manifest("electron_content_browser_manifest_overlay") {
|
service_manifest("electron_content_browser_manifest_overlay") {
|
||||||
|
|
|
@ -51,8 +51,6 @@
|
||||||
#include "brightray/browser/inspectable_web_contents.h"
|
#include "brightray/browser/inspectable_web_contents.h"
|
||||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
#include "brightray/browser/inspectable_web_contents_view.h"
|
||||||
#include "chrome/browser/browser_process.h"
|
#include "chrome/browser/browser_process.h"
|
||||||
#include "chrome/browser/printing/print_preview_message_handler.h"
|
|
||||||
#include "chrome/browser/printing/print_view_manager_basic.h"
|
|
||||||
#include "chrome/browser/ssl/security_state_tab_helper.h"
|
#include "chrome/browser/ssl/security_state_tab_helper.h"
|
||||||
#include "content/browser/frame_host/frame_tree_node.h"
|
#include "content/browser/frame_host/frame_tree_node.h"
|
||||||
#include "content/browser/frame_host/render_frame_host_manager.h"
|
#include "content/browser/frame_host/render_frame_host_manager.h"
|
||||||
|
@ -81,6 +79,7 @@
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
#include "native_mate/object_template_builder.h"
|
#include "native_mate/object_template_builder.h"
|
||||||
#include "net/url_request/url_request_context.h"
|
#include "net/url_request/url_request_context.h"
|
||||||
|
#include "printing/buildflags/buildflags.h"
|
||||||
#include "third_party/blink/public/platform/web_input_event.h"
|
#include "third_party/blink/public/platform/web_input_event.h"
|
||||||
#include "third_party/blink/public/web/web_find_options.h"
|
#include "third_party/blink/public/web/web_find_options.h"
|
||||||
#include "ui/display/screen.h"
|
#include "ui/display/screen.h"
|
||||||
|
@ -101,6 +100,11 @@
|
||||||
#include "ui/gfx/font_render_params.h"
|
#include "ui/gfx/font_render_params.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if BUILDFLAG(ENABLE_PRINTING)
|
||||||
|
#include "atom/browser/atom_print_preview_message_handler.h"
|
||||||
|
#include "chrome/browser/printing/print_view_manager_basic.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "atom/common/node_includes.h"
|
#include "atom/common/node_includes.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -110,6 +114,7 @@ struct PrintSettings {
|
||||||
bool print_background;
|
bool print_background;
|
||||||
base::string16 device_name;
|
base::string16 device_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace mate {
|
namespace mate {
|
||||||
|
@ -1423,6 +1428,7 @@ bool WebContents::IsCurrentlyAudible() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::Print(mate::Arguments* args) {
|
void WebContents::Print(mate::Arguments* args) {
|
||||||
|
#if BUILDFLAG(ENABLE_PRINTING)
|
||||||
PrintSettings settings = {false, false, base::string16()};
|
PrintSettings settings = {false, false, base::string16()};
|
||||||
if (args->Length() >= 1 && !args->GetNext(&settings)) {
|
if (args->Length() >= 1 && !args->GetNext(&settings)) {
|
||||||
args->ThrowError();
|
args->ThrowError();
|
||||||
|
@ -1441,20 +1447,29 @@ void WebContents::Print(mate::Arguments* args) {
|
||||||
print_view_manager_basic_ptr->PrintNow(
|
print_view_manager_basic_ptr->PrintNow(
|
||||||
web_contents()->GetMainFrame(), settings.silent,
|
web_contents()->GetMainFrame(), settings.silent,
|
||||||
settings.print_background, settings.device_name);
|
settings.print_background, settings.device_name);
|
||||||
|
#else
|
||||||
|
LOG(ERROR) << "Printing is disabled";
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<printing::PrinterBasicInfo> WebContents::GetPrinterList() {
|
std::vector<printing::PrinterBasicInfo> WebContents::GetPrinterList() {
|
||||||
std::vector<printing::PrinterBasicInfo> printers;
|
std::vector<printing::PrinterBasicInfo> printers;
|
||||||
|
|
||||||
|
#if BUILDFLAG(ENABLE_PRINTING)
|
||||||
auto print_backend = printing::PrintBackend::CreateInstance(nullptr);
|
auto print_backend = printing::PrintBackend::CreateInstance(nullptr);
|
||||||
base::ThreadRestrictions::ScopedAllowIO allow_io;
|
base::ThreadRestrictions::ScopedAllowIO allow_io;
|
||||||
print_backend->EnumeratePrinters(&printers);
|
print_backend->EnumeratePrinters(&printers);
|
||||||
|
#endif
|
||||||
|
|
||||||
return printers;
|
return printers;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::PrintToPDF(const base::DictionaryValue& setting,
|
void WebContents::PrintToPDF(const base::DictionaryValue& setting,
|
||||||
const PrintToPDFCallback& callback) {
|
const PrintToPDFCallback& callback) {
|
||||||
printing::PrintPreviewMessageHandler::FromWebContents(web_contents())
|
#if BUILDFLAG(ENABLE_PRINTING)
|
||||||
|
AtomPrintPreviewMessageHandler::FromWebContents(web_contents())
|
||||||
->PrintToPDF(setting, callback);
|
->PrintToPDF(setting, callback);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::AddWorkSpace(mate::Arguments* args,
|
void WebContents::AddWorkSpace(mate::Arguments* args,
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
#include "net/base/escape.h"
|
#include "net/base/escape.h"
|
||||||
#include "net/ssl/ssl_cert_request_info.h"
|
#include "net/ssl/ssl_cert_request_info.h"
|
||||||
#include "ppapi/host/ppapi_host.h"
|
#include "ppapi/host/ppapi_host.h"
|
||||||
|
#include "printing/buildflags/buildflags.h"
|
||||||
#include "services/device/public/cpp/geolocation/location_provider.h"
|
#include "services/device/public/cpp/geolocation/location_provider.h"
|
||||||
#include "services/network/public/cpp/resource_request_body.h"
|
#include "services/network/public/cpp/resource_request_body.h"
|
||||||
#include "services/proxy_resolver/public/mojom/proxy_resolver.mojom.h"
|
#include "services/proxy_resolver/public/mojom/proxy_resolver.mojom.h"
|
||||||
|
@ -88,6 +89,10 @@
|
||||||
#include "chrome/browser/speech/tts_message_filter.h"
|
#include "chrome/browser/speech/tts_message_filter.h"
|
||||||
#endif // BUILDFLAG(ENABLE_TTS)
|
#endif // BUILDFLAG(ENABLE_TTS)
|
||||||
|
|
||||||
|
#if BUILDFLAG(ENABLE_PRINTING)
|
||||||
|
#include "chrome/services/printing/public/mojom/constants.mojom.h"
|
||||||
|
#endif // BUILDFLAG(ENABLE_PRINTING)
|
||||||
|
|
||||||
using content::BrowserThread;
|
using content::BrowserThread;
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
@ -209,7 +214,9 @@ void AtomBrowserClient::RenderProcessWillLaunch(
|
||||||
if (IsProcessObserved(process_id))
|
if (IsProcessObserved(process_id))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#if BUILDFLAG(ENABLE_PRINTING)
|
||||||
host->AddFilter(new printing::PrintingMessageFilter(process_id));
|
host->AddFilter(new printing::PrintingMessageFilter(process_id));
|
||||||
|
#endif
|
||||||
|
|
||||||
#if BUILDFLAG(ENABLE_TTS)
|
#if BUILDFLAG(ENABLE_TTS)
|
||||||
host->AddFilter(new TtsMessageFilter(host->GetBrowserContext()));
|
host->AddFilter(new TtsMessageFilter(host->GetBrowserContext()));
|
||||||
|
@ -535,6 +542,12 @@ void AtomBrowserClient::RegisterOutOfProcessServices(
|
||||||
(*services)[proxy_resolver::mojom::kProxyResolverServiceName] =
|
(*services)[proxy_resolver::mojom::kProxyResolverServiceName] =
|
||||||
base::BindRepeating(&l10n_util::GetStringUTF16,
|
base::BindRepeating(&l10n_util::GetStringUTF16,
|
||||||
IDS_UTILITY_PROCESS_PROXY_RESOLVER_NAME);
|
IDS_UTILITY_PROCESS_PROXY_RESOLVER_NAME);
|
||||||
|
|
||||||
|
#if BUILDFLAG(ENABLE_PRINTING)
|
||||||
|
(*services)[printing::mojom::kChromePrintingServiceName] =
|
||||||
|
base::BindRepeating(&l10n_util::GetStringUTF16,
|
||||||
|
IDS_UTILITY_PROCESS_PRINTING_SERVICE_NAME);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<base::Value> AtomBrowserClient::GetServiceManifestOverlay(
|
std::unique_ptr<base::Value> AtomBrowserClient::GetServiceManifestOverlay(
|
||||||
|
|
134
atom/browser/atom_print_preview_message_handler.cc
Normal file
134
atom/browser/atom_print_preview_message_handler.cc
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
// 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 "atom/browser/atom_print_preview_message_handler.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "base/bind.h"
|
||||||
|
#include "base/memory/ref_counted.h"
|
||||||
|
#include "base/memory/ref_counted_memory.h"
|
||||||
|
#include "base/memory/shared_memory.h"
|
||||||
|
#include "base/memory/shared_memory_handle.h"
|
||||||
|
#include "chrome/browser/browser_process.h"
|
||||||
|
#include "chrome/browser/printing/print_job_manager.h"
|
||||||
|
#include "chrome/browser/printing/print_preview_dialog_controller.h"
|
||||||
|
#include "chrome/browser/printing/print_view_manager.h"
|
||||||
|
#include "chrome/browser/printing/printer_query.h"
|
||||||
|
#include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
|
||||||
|
#include "components/printing/browser/print_composite_client.h"
|
||||||
|
#include "components/printing/browser/print_manager_utils.h"
|
||||||
|
#include "components/printing/common/print_messages.h"
|
||||||
|
#include "components/services/pdf_compositor/public/cpp/pdf_service_mojo_types.h"
|
||||||
|
#include "components/services/pdf_compositor/public/cpp/pdf_service_mojo_utils.h"
|
||||||
|
#include "content/public/browser/browser_thread.h"
|
||||||
|
#include "content/public/browser/render_frame_host.h"
|
||||||
|
#include "content/public/browser/render_process_host.h"
|
||||||
|
#include "content/public/browser/web_contents.h"
|
||||||
|
#include "content/public/browser/web_ui.h"
|
||||||
|
#include "printing/page_size_margins.h"
|
||||||
|
#include "printing/print_job_constants.h"
|
||||||
|
#include "printing/print_settings.h"
|
||||||
|
|
||||||
|
#include "atom/common/node_includes.h"
|
||||||
|
|
||||||
|
using content::BrowserThread;
|
||||||
|
using content::WebContents;
|
||||||
|
|
||||||
|
DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::AtomPrintPreviewMessageHandler);
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
char* CopyPDFDataOnIOThread(
|
||||||
|
const PrintHostMsg_DidPreviewDocument_Params& params) {
|
||||||
|
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||||
|
const PrintHostMsg_DidPrintContent_Params& content = params.content;
|
||||||
|
std::unique_ptr<base::SharedMemory> shared_buf(
|
||||||
|
new base::SharedMemory(content.metafile_data_handle, true));
|
||||||
|
if (!shared_buf->Map(content.data_size))
|
||||||
|
return nullptr;
|
||||||
|
char* pdf_data = new char[content.data_size];
|
||||||
|
memcpy(pdf_data, shared_buf->memory(), content.data_size);
|
||||||
|
return pdf_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreeNodeBufferData(char* data, void* hint) {
|
||||||
|
delete[] data;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
AtomPrintPreviewMessageHandler::AtomPrintPreviewMessageHandler(
|
||||||
|
WebContents* web_contents)
|
||||||
|
: printing::PrintPreviewMessageHandler(web_contents),
|
||||||
|
weak_ptr_factory_(this) {
|
||||||
|
DCHECK(web_contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
AtomPrintPreviewMessageHandler::~AtomPrintPreviewMessageHandler() {}
|
||||||
|
|
||||||
|
void AtomPrintPreviewMessageHandler::OnMetafileReadyForPrinting(
|
||||||
|
content::RenderFrameHost* render_frame_host,
|
||||||
|
const PrintHostMsg_DidPreviewDocument_Params& params,
|
||||||
|
const PrintHostMsg_PreviewIds& ids) {
|
||||||
|
printing::PrintPreviewMessageHandler::OnMetafileReadyForPrinting(
|
||||||
|
render_frame_host, params, ids);
|
||||||
|
|
||||||
|
BrowserThread::PostTaskAndReplyWithResult(
|
||||||
|
BrowserThread::IO, FROM_HERE, base::Bind(&CopyPDFDataOnIOThread, params),
|
||||||
|
base::Bind(&AtomPrintPreviewMessageHandler::RunPrintToPDFCallback,
|
||||||
|
base::Unretained(this), ids.request_id,
|
||||||
|
params.content.data_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AtomPrintPreviewMessageHandler::OnPrintPreviewFailed(
|
||||||
|
int document_cookie,
|
||||||
|
const PrintHostMsg_PreviewIds& ids) {
|
||||||
|
printing::PrintPreviewMessageHandler::OnPrintPreviewFailed(document_cookie,
|
||||||
|
ids);
|
||||||
|
|
||||||
|
RunPrintToPDFCallback(ids.request_id, 0, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AtomPrintPreviewMessageHandler::PrintToPDF(
|
||||||
|
const base::DictionaryValue& options,
|
||||||
|
const PrintToPDFCallback& callback) {
|
||||||
|
int request_id;
|
||||||
|
options.GetInteger(printing::kPreviewRequestID, &request_id);
|
||||||
|
print_to_pdf_callback_map_[request_id] = callback;
|
||||||
|
|
||||||
|
content::RenderFrameHost* rfh = web_contents()->GetMainFrame();
|
||||||
|
rfh->Send(new PrintMsg_PrintPreview(rfh->GetRoutingID(), options));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AtomPrintPreviewMessageHandler::RunPrintToPDFCallback(int request_id,
|
||||||
|
uint32_t data_size,
|
||||||
|
char* data) {
|
||||||
|
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||||
|
|
||||||
|
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||||
|
v8::Locker locker(isolate);
|
||||||
|
v8::HandleScope handle_scope(isolate);
|
||||||
|
if (data) {
|
||||||
|
v8::Local<v8::Value> buffer =
|
||||||
|
node::Buffer::New(isolate, data, static_cast<size_t>(data_size),
|
||||||
|
&FreeNodeBufferData, nullptr)
|
||||||
|
.ToLocalChecked();
|
||||||
|
print_to_pdf_callback_map_[request_id].Run(v8::Null(isolate), buffer);
|
||||||
|
} else {
|
||||||
|
v8::Local<v8::String> error_message =
|
||||||
|
v8::String::NewFromUtf8(isolate, "Failed to generate PDF");
|
||||||
|
print_to_pdf_callback_map_[request_id].Run(
|
||||||
|
v8::Exception::Error(error_message), v8::Null(isolate));
|
||||||
|
}
|
||||||
|
print_to_pdf_callback_map_.erase(request_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace atom
|
52
atom/browser/atom_print_preview_message_handler.h
Normal file
52
atom/browser/atom_print_preview_message_handler.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
// 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 ATOM_BROWSER_ATOM_PRINT_PREVIEW_MESSAGE_HANDLER_H_
|
||||||
|
#define ATOM_BROWSER_ATOM_PRINT_PREVIEW_MESSAGE_HANDLER_H_
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "base/memory/weak_ptr.h"
|
||||||
|
#include "chrome/browser/printing/print_preview_message_handler.h"
|
||||||
|
#include "content/public/browser/web_contents_user_data.h"
|
||||||
|
#include "v8/include/v8.h"
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
// Manages the print preview handling for a WebContents.
|
||||||
|
class AtomPrintPreviewMessageHandler
|
||||||
|
: public printing::PrintPreviewMessageHandler,
|
||||||
|
public content::WebContentsUserData<AtomPrintPreviewMessageHandler> {
|
||||||
|
public:
|
||||||
|
~AtomPrintPreviewMessageHandler() override;
|
||||||
|
|
||||||
|
using PrintToPDFCallback =
|
||||||
|
base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>)>;
|
||||||
|
|
||||||
|
void PrintToPDF(const base::DictionaryValue& options,
|
||||||
|
const PrintToPDFCallback& callback);
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit AtomPrintPreviewMessageHandler(content::WebContents* web_contents);
|
||||||
|
friend class content::WebContentsUserData<AtomPrintPreviewMessageHandler>;
|
||||||
|
typedef std::map<int, PrintToPDFCallback> PrintToPDFCallbackMap;
|
||||||
|
|
||||||
|
void OnMetafileReadyForPrinting(
|
||||||
|
content::RenderFrameHost* render_frame_host,
|
||||||
|
const PrintHostMsg_DidPreviewDocument_Params& params,
|
||||||
|
const PrintHostMsg_PreviewIds& ids) override;
|
||||||
|
void OnPrintPreviewFailed(int document_cookie,
|
||||||
|
const PrintHostMsg_PreviewIds& ids) override;
|
||||||
|
void RunPrintToPDFCallback(int request_id, uint32_t data_size, char* data);
|
||||||
|
|
||||||
|
PrintToPDFCallbackMap print_to_pdf_callback_map_;
|
||||||
|
|
||||||
|
base::WeakPtrFactory<PrintPreviewMessageHandler> weak_ptr_factory_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(AtomPrintPreviewMessageHandler);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
|
|
||||||
|
#endif // ATOM_BROWSER_ATOM_PRINT_PREVIEW_MESSAGE_HANDLER_H_
|
|
@ -21,8 +21,6 @@
|
||||||
#include "base/json/json_reader.h"
|
#include "base/json/json_reader.h"
|
||||||
#include "base/task_scheduler/post_task.h"
|
#include "base/task_scheduler/post_task.h"
|
||||||
#include "base/threading/sequenced_task_runner_handle.h"
|
#include "base/threading/sequenced_task_runner_handle.h"
|
||||||
#include "chrome/browser/printing/print_preview_message_handler.h"
|
|
||||||
#include "chrome/browser/printing/print_view_manager_basic.h"
|
|
||||||
#include "chrome/browser/ssl/security_state_tab_helper.h"
|
#include "chrome/browser/ssl/security_state_tab_helper.h"
|
||||||
#include "chrome/browser/ui/browser_dialogs.h"
|
#include "chrome/browser/ui/browser_dialogs.h"
|
||||||
#include "chrome/common/pref_names.h"
|
#include "chrome/common/pref_names.h"
|
||||||
|
@ -38,12 +36,18 @@
|
||||||
#include "content/public/browser/render_widget_host.h"
|
#include "content/public/browser/render_widget_host.h"
|
||||||
#include "content/public/browser/security_style_explanation.h"
|
#include "content/public/browser/security_style_explanation.h"
|
||||||
#include "content/public/browser/security_style_explanations.h"
|
#include "content/public/browser/security_style_explanations.h"
|
||||||
|
#include "printing/buildflags/buildflags.h"
|
||||||
#include "storage/browser/fileapi/isolated_context.h"
|
#include "storage/browser/fileapi/isolated_context.h"
|
||||||
|
|
||||||
#if BUILDFLAG(ENABLE_OSR)
|
#if BUILDFLAG(ENABLE_OSR)
|
||||||
#include "atom/browser/osr/osr_render_widget_host_view.h"
|
#include "atom/browser/osr/osr_render_widget_host_view.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if BUILDFLAG(ENABLE_PRINTING)
|
||||||
|
#include "atom/browser/atom_print_preview_message_handler.h"
|
||||||
|
#include "chrome/browser/printing/print_view_manager_basic.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
using content::BrowserThread;
|
using content::BrowserThread;
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
@ -173,8 +177,10 @@ void CommonWebContentsDelegate::InitWithWebContents(
|
||||||
browser_context_ = browser_context;
|
browser_context_ = browser_context;
|
||||||
web_contents->SetDelegate(this);
|
web_contents->SetDelegate(this);
|
||||||
|
|
||||||
|
#if BUILDFLAG(ENABLE_PRINTING)
|
||||||
printing::PrintViewManagerBasic::CreateForWebContents(web_contents);
|
printing::PrintViewManagerBasic::CreateForWebContents(web_contents);
|
||||||
printing::PrintPreviewMessageHandler::CreateForWebContents(web_contents);
|
AtomPrintPreviewMessageHandler::CreateForWebContents(web_contents);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Determien whether the WebContents is offscreen.
|
// Determien whether the WebContents is offscreen.
|
||||||
auto* web_preferences = WebContentsPreferences::From(web_contents);
|
auto* web_preferences = WebContentsPreferences::From(web_contents);
|
||||||
|
|
|
@ -5,5 +5,3 @@
|
||||||
// Multiply-included file, no traditional include guard.
|
// Multiply-included file, no traditional include guard.
|
||||||
|
|
||||||
#include "atom/common/api/api_messages.h"
|
#include "atom/common/api/api_messages.h"
|
||||||
#include "chrome/common/chrome_utility_printing_messages.h"
|
|
||||||
#include "chrome/common/print_messages.h"
|
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
#include "base/path_service.h"
|
#include "base/path_service.h"
|
||||||
#include "base/process/process_handle.h"
|
#include "base/process/process_handle.h"
|
||||||
#include "brightray/common/application_info.h"
|
#include "brightray/common/application_info.h"
|
||||||
#include "chrome/renderer/printing/print_web_view_helper.h"
|
|
||||||
#include "content/public/renderer/render_frame.h"
|
#include "content/public/renderer/render_frame.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
#include "third_party/blink/public/web/blink.h"
|
#include "third_party/blink/public/web/blink.h"
|
||||||
|
|
|
@ -19,13 +19,13 @@
|
||||||
#include "base/command_line.h"
|
#include "base/command_line.h"
|
||||||
#include "base/strings/string_split.h"
|
#include "base/strings/string_split.h"
|
||||||
#include "base/strings/stringprintf.h"
|
#include "base/strings/stringprintf.h"
|
||||||
#include "chrome/renderer/printing/print_web_view_helper.h"
|
|
||||||
#include "content/public/common/content_constants.h"
|
#include "content/public/common/content_constants.h"
|
||||||
#include "content/public/common/content_switches.h"
|
#include "content/public/common/content_switches.h"
|
||||||
#include "content/public/renderer/render_frame.h"
|
#include "content/public/renderer/render_frame.h"
|
||||||
#include "content/public/renderer/render_view.h"
|
#include "content/public/renderer/render_view.h"
|
||||||
#include "electron/buildflags/buildflags.h"
|
#include "electron/buildflags/buildflags.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
|
#include "printing/buildflags/buildflags.h"
|
||||||
#include "third_party/blink/public/web/blink.h"
|
#include "third_party/blink/public/web/blink.h"
|
||||||
#include "third_party/blink/public/web/web_custom_element.h" // NOLINT(build/include_alpha)
|
#include "third_party/blink/public/web/web_custom_element.h" // NOLINT(build/include_alpha)
|
||||||
#include "third_party/blink/public/web/web_frame_widget.h"
|
#include "third_party/blink/public/web/web_frame_widget.h"
|
||||||
|
@ -54,6 +54,11 @@
|
||||||
#include "chrome/renderer/tts_dispatcher.h"
|
#include "chrome/renderer/tts_dispatcher.h"
|
||||||
#endif // BUILDFLAG(ENABLE_TTS)
|
#endif // BUILDFLAG(ENABLE_TTS)
|
||||||
|
|
||||||
|
#if BUILDFLAG(ENABLE_PRINTING)
|
||||||
|
#include "chrome/renderer/printing/chrome_print_render_frame_helper_delegate.h"
|
||||||
|
#include "components/printing/renderer/print_render_frame_helper.h"
|
||||||
|
#endif // BUILDFLAG(ENABLE_PRINTING)
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -173,7 +178,10 @@ void RendererClientBase::RenderFrameCreated(
|
||||||
new PepperHelper(render_frame);
|
new PepperHelper(render_frame);
|
||||||
#endif
|
#endif
|
||||||
new ContentSettingsObserver(render_frame);
|
new ContentSettingsObserver(render_frame);
|
||||||
new printing::PrintWebViewHelper(render_frame);
|
#if BUILDFLAG(ENABLE_PRINTING)
|
||||||
|
new printing::PrintRenderFrameHelper(
|
||||||
|
render_frame, std::make_unique<ChromePrintRenderFrameHelperDelegate>());
|
||||||
|
#endif
|
||||||
|
|
||||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||||
// Allow access to file scheme from pdf viewer.
|
// Allow access to file scheme from pdf viewer.
|
||||||
|
|
|
@ -4,30 +4,79 @@
|
||||||
|
|
||||||
#include "atom/utility/atom_content_utility_client.h"
|
#include "atom/utility/atom_content_utility_client.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "base/command_line.h"
|
||||||
#include "content/public/child/child_thread.h"
|
#include "content/public/child/child_thread.h"
|
||||||
|
#include "content/public/common/service_manager_connection.h"
|
||||||
|
#include "content/public/common/simple_connection_filter.h"
|
||||||
#include "services/proxy_resolver/proxy_resolver_service.h"
|
#include "services/proxy_resolver/proxy_resolver_service.h"
|
||||||
#include "services/proxy_resolver/public/mojom/proxy_resolver.mojom.h"
|
#include "services/proxy_resolver/public/mojom/proxy_resolver.mojom.h"
|
||||||
|
#include "services/service_manager/sandbox/switches.h"
|
||||||
|
|
||||||
|
#if BUILDFLAG(ENABLE_PRINTING)
|
||||||
|
#include "chrome/services/printing/printing_service.h"
|
||||||
|
#include "chrome/services/printing/public/mojom/constants.mojom.h"
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
#include "chrome/utility/printing_handler_win.h"
|
#include "chrome/services/printing/pdf_to_emf_converter_factory.h"
|
||||||
#endif
|
#include "chrome/utility/printing_handler.h"
|
||||||
|
#endif // defined(OS_WIN)
|
||||||
|
|
||||||
|
#endif // BUILDFLAG(ENABLE_PRINTING)
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
AtomContentUtilityClient::AtomContentUtilityClient() {
|
AtomContentUtilityClient::AtomContentUtilityClient() : elevated_(false) {
|
||||||
#if defined(OS_WIN)
|
#if BUILDFLAG(ENABLE_PRINTING) && defined(OS_WIN)
|
||||||
handlers_.push_back(std::make_unique<printing::PrintingHandlerWin>());
|
printing_handler_ = std::make_unique<printing::PrintingHandler>();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
AtomContentUtilityClient::~AtomContentUtilityClient() {}
|
AtomContentUtilityClient::~AtomContentUtilityClient() {}
|
||||||
|
|
||||||
bool AtomContentUtilityClient::OnMessageReceived(const IPC::Message& message) {
|
// The guts of this came from the chromium implementation
|
||||||
|
// https://cs.chromium.org/chromium/src/chrome/utility/
|
||||||
|
// chrome_content_utility_client.cc?sq=package:chromium&dr=CSs&g=0&l=142
|
||||||
|
void AtomContentUtilityClient::UtilityThreadStarted() {
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
for (const auto& handler : handlers_) {
|
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||||
if (handler->OnMessageReceived(message))
|
elevated_ = command_line->HasSwitch(
|
||||||
return true;
|
service_manager::switches::kNoSandboxAndElevatedPrivileges);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
content::ServiceManagerConnection* connection =
|
||||||
|
content::ChildThread::Get()->GetServiceManagerConnection();
|
||||||
|
|
||||||
|
// NOTE: Some utility process instances are not connected to the Service
|
||||||
|
// Manager. Nothing left to do in that case.
|
||||||
|
if (!connection)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto registry = std::make_unique<service_manager::BinderRegistry>();
|
||||||
|
// If our process runs with elevated privileges, only add elevated Mojo
|
||||||
|
// interfaces to the interface registry.
|
||||||
|
if (!elevated_) {
|
||||||
|
#if BUILDFLAG(ENABLE_PRINTING) && defined(OS_WIN)
|
||||||
|
// TODO(crbug.com/798782): remove when the Cloud print chrome/service is
|
||||||
|
// removed.
|
||||||
|
registry->AddInterface(
|
||||||
|
base::BindRepeating(printing::PdfToEmfConverterFactory::Create),
|
||||||
|
base::ThreadTaskRunnerHandle::Get());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connection->AddConnectionFilter(
|
||||||
|
std::make_unique<content::SimpleConnectionFilter>(std::move(registry)));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AtomContentUtilityClient::OnMessageReceived(const IPC::Message& message) {
|
||||||
|
if (elevated_)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#if BUILDFLAG(ENABLE_PRINTING) && defined(OS_WIN)
|
||||||
|
if (printing_handler_->OnMessageReceived(message))
|
||||||
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -41,6 +90,13 @@ void AtomContentUtilityClient::RegisterServices(StaticServiceMap* services) {
|
||||||
base::BindRepeating(&proxy_resolver::ProxyResolverService::CreateService);
|
base::BindRepeating(&proxy_resolver::ProxyResolverService::CreateService);
|
||||||
services->emplace(proxy_resolver::mojom::kProxyResolverServiceName,
|
services->emplace(proxy_resolver::mojom::kProxyResolverServiceName,
|
||||||
proxy_resolver_info);
|
proxy_resolver_info);
|
||||||
|
|
||||||
|
#if BUILDFLAG(ENABLE_PRINTING)
|
||||||
|
service_manager::EmbeddedServiceInfo printing_info;
|
||||||
|
printing_info.factory =
|
||||||
|
base::BindRepeating(&printing::PrintingService::CreateService);
|
||||||
|
services->emplace(printing::mojom::kChromePrintingServiceName, printing_info);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|
|
@ -10,8 +10,11 @@
|
||||||
|
|
||||||
#include "base/compiler_specific.h"
|
#include "base/compiler_specific.h"
|
||||||
#include "content/public/utility/content_utility_client.h"
|
#include "content/public/utility/content_utility_client.h"
|
||||||
|
#include "printing/buildflags/buildflags.h"
|
||||||
|
|
||||||
class UtilityMessageHandler;
|
#if BUILDFLAG(ENABLE_PRINTING) && defined(OS_WIN)
|
||||||
|
#include "chrome/utility/printing_handler.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
@ -20,15 +23,17 @@ class AtomContentUtilityClient : public content::ContentUtilityClient {
|
||||||
AtomContentUtilityClient();
|
AtomContentUtilityClient();
|
||||||
~AtomContentUtilityClient() override;
|
~AtomContentUtilityClient() override;
|
||||||
|
|
||||||
|
void UtilityThreadStarted() override;
|
||||||
bool OnMessageReceived(const IPC::Message& message) override;
|
bool OnMessageReceived(const IPC::Message& message) override;
|
||||||
void RegisterServices(StaticServiceMap* services) override;
|
void RegisterServices(StaticServiceMap* services) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#if defined(OS_WIN)
|
#if BUILDFLAG(ENABLE_PRINTING) && defined(OS_WIN)
|
||||||
typedef std::vector<std::unique_ptr<UtilityMessageHandler>> Handlers;
|
std::unique_ptr<printing::PrintingHandler> printing_handler_;
|
||||||
Handlers handlers_;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool elevated_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(AtomContentUtilityClient);
|
DISALLOW_COPY_AND_ASSIGN(AtomContentUtilityClient);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,4 +10,6 @@ enable_cdm_host_verification = false
|
||||||
proprietary_codecs = true
|
proprietary_codecs = true
|
||||||
ffmpeg_branding = "Chrome"
|
ffmpeg_branding = "Chrome"
|
||||||
|
|
||||||
|
enable_basic_printing = true
|
||||||
|
|
||||||
is_cfi = false
|
is_cfi = false
|
||||||
|
|
|
@ -5,10 +5,13 @@
|
||||||
#include "chrome/browser/browser_process_impl.h"
|
#include "chrome/browser/browser_process_impl.h"
|
||||||
|
|
||||||
#include "chrome/browser/printing/print_job_manager.h"
|
#include "chrome/browser/printing/print_job_manager.h"
|
||||||
|
#include "printing/buildflags/buildflags.h"
|
||||||
#include "ui/base/l10n/l10n_util.h"
|
#include "ui/base/l10n/l10n_util.h"
|
||||||
|
|
||||||
BrowserProcessImpl::BrowserProcessImpl()
|
BrowserProcessImpl::BrowserProcessImpl() : print_job_manager_(nullptr) {
|
||||||
: print_job_manager_(new printing::PrintJobManager) {
|
#if BUILDFLAG(ENABLE_PRINTING)
|
||||||
|
print_job_manager_.reset(new printing::PrintJobManager());
|
||||||
|
#endif
|
||||||
g_browser_process = this;
|
g_browser_process = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,684 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#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/ref_counted_delete_on_sequence.h"
|
|
||||||
#include "base/sequenced_task_runner.h"
|
|
||||||
#include "base/task_scheduler/post_task.h"
|
|
||||||
#include "base/threading/sequenced_task_runner_handle.h"
|
|
||||||
#include "base/threading/thread_restrictions.h"
|
|
||||||
#include "base/threading/thread_task_runner_handle.h"
|
|
||||||
#include "chrome/common/chrome_utility_printing_messages.h"
|
|
||||||
#include "content/browser/utility_process_host.h"
|
|
||||||
#include "content/browser/utility_process_host_client.h"
|
|
||||||
#include "content/public/browser/browser_thread.h"
|
|
||||||
#include "content/public/browser/child_process_data.h"
|
|
||||||
#include "printing/emf_win.h"
|
|
||||||
#include "printing/pdf_render_settings.h"
|
|
||||||
#include "ui/base/l10n/l10n_util.h"
|
|
||||||
|
|
||||||
using content::BrowserThread;
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
void CloseFileOnBlockingTaskRunner(base::File temp_file) {
|
|
||||||
base::AssertBlockingAllowed();
|
|
||||||
temp_file.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
class PdfConverterImpl;
|
|
||||||
|
|
||||||
// Allows to delete temporary directory after all temporary files created inside
|
|
||||||
// are closed. Windows cannot delete directory with opened files. Directory is
|
|
||||||
// used to store PDF and metafiles. PDF should be gone by the time utility
|
|
||||||
// process exits. Metafiles should be gone when all LazyEmf destroyed.
|
|
||||||
class RefCountedTempDir
|
|
||||||
: public base::RefCountedDeleteOnSequence<RefCountedTempDir> {
|
|
||||||
public:
|
|
||||||
RefCountedTempDir()
|
|
||||||
: base::RefCountedDeleteOnSequence<RefCountedTempDir>(
|
|
||||||
base::SequencedTaskRunnerHandle::Get()) {
|
|
||||||
ignore_result(temp_dir_.CreateUniqueTempDir());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsValid() const { return temp_dir_.IsValid(); }
|
|
||||||
const base::FilePath& GetPath() const { return temp_dir_.GetPath(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class base::RefCountedDeleteOnSequence<RefCountedTempDir>;
|
|
||||||
friend class base::DeleteHelper<RefCountedTempDir>;
|
|
||||||
|
|
||||||
~RefCountedTempDir() {}
|
|
||||||
|
|
||||||
base::ScopedTempDir temp_dir_;
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(RefCountedTempDir);
|
|
||||||
};
|
|
||||||
|
|
||||||
class TempFile {
|
|
||||||
public:
|
|
||||||
explicit TempFile(base::File file)
|
|
||||||
: file_(std::move(file)),
|
|
||||||
blocking_task_runner_(base::SequencedTaskRunnerHandle::Get()) {
|
|
||||||
base::AssertBlockingAllowed();
|
|
||||||
}
|
|
||||||
~TempFile() {
|
|
||||||
blocking_task_runner_->PostTask(
|
|
||||||
FROM_HERE, base::BindOnce(&CloseFileOnBlockingTaskRunner,
|
|
||||||
base::Passed(std::move(file_))));
|
|
||||||
}
|
|
||||||
|
|
||||||
base::File& file() { return file_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
base::File file_;
|
|
||||||
const scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(TempFile);
|
|
||||||
};
|
|
||||||
|
|
||||||
using ScopedTempFile = std::unique_ptr<TempFile>;
|
|
||||||
|
|
||||||
// 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
|
|
||||||
// can't open file handles. We need file handles to reliably delete temporary
|
|
||||||
// files, and to efficiently interact with utility process.
|
|
||||||
class LazyEmf : public MetafilePlayer {
|
|
||||||
public:
|
|
||||||
LazyEmf(const scoped_refptr<RefCountedTempDir>& temp_dir, ScopedTempFile file)
|
|
||||||
: temp_dir_(temp_dir), file_(std::move(file)) {
|
|
||||||
CHECK(file_);
|
|
||||||
}
|
|
||||||
~LazyEmf() override { Close(); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// MetafilePlayer:
|
|
||||||
bool SafePlayback(HDC hdc) const override;
|
|
||||||
|
|
||||||
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);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// 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 UI thread, IO thread and |blocking_task_runner_|.
|
|
||||||
// Internal workflow is following:
|
|
||||||
// 1. Create instance on the UI thread. (files_, settings_,)
|
|
||||||
// 2. Create pdf file on |blocking_task_runner_|.
|
|
||||||
// 3. Start utility process and start conversion on the IO thread.
|
|
||||||
// 4. Utility process returns page count.
|
|
||||||
// 5. For each page:
|
|
||||||
// 1. Clients requests page with file handle to a temp file.
|
|
||||||
// 2. Utility converts the page, save it to the file and reply.
|
|
||||||
//
|
|
||||||
// All these steps work sequentially, so no data should be accessed
|
|
||||||
// simultaneously by several threads.
|
|
||||||
class PdfConverterUtilityProcessHostClient
|
|
||||||
: public content::UtilityProcessHostClient {
|
|
||||||
public:
|
|
||||||
PdfConverterUtilityProcessHostClient(
|
|
||||||
base::WeakPtr<PdfConverterImpl> converter,
|
|
||||||
const PdfRenderSettings& settings);
|
|
||||||
|
|
||||||
void Start(const scoped_refptr<base::RefCountedMemory>& data,
|
|
||||||
const PdfConverter::StartCallback& start_callback);
|
|
||||||
|
|
||||||
void GetPage(int page_number,
|
|
||||||
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);
|
|
||||||
|
|
||||||
private:
|
|
||||||
class GetPageCallbackData {
|
|
||||||
public:
|
|
||||||
GetPageCallbackData(int page_number, PdfConverter::GetPageCallback callback)
|
|
||||||
: page_number_(page_number), callback_(callback) {}
|
|
||||||
|
|
||||||
GetPageCallbackData(GetPageCallbackData&& other) {
|
|
||||||
*this = std::move(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
GetPageCallbackData& operator=(GetPageCallbackData&& rhs) {
|
|
||||||
page_number_ = rhs.page_number_;
|
|
||||||
callback_ = rhs.callback_;
|
|
||||||
file_ = std::move(rhs.file_);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
int page_number() const { return page_number_; }
|
|
||||||
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_;
|
|
||||||
|
|
||||||
PdfConverter::GetPageCallback callback_;
|
|
||||||
ScopedTempFile file_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(GetPageCallbackData);
|
|
||||||
};
|
|
||||||
|
|
||||||
~PdfConverterUtilityProcessHostClient() override;
|
|
||||||
|
|
||||||
bool OnMessageReceived(const IPC::Message& message) override;
|
|
||||||
|
|
||||||
// Helper functions: must be overridden by subclasses
|
|
||||||
// Set the process name
|
|
||||||
base::string16 GetName() const;
|
|
||||||
// Create a metafileplayer subclass file from a temporary file.
|
|
||||||
std::unique_ptr<MetafilePlayer> GetFileFromTemp(ScopedTempFile temp_file);
|
|
||||||
// Send the messages to Start, GetPage, and Stop.
|
|
||||||
void SendStartMessage(IPC::PlatformFileForTransit transit);
|
|
||||||
void SendGetPageMessage(int page_number, IPC::PlatformFileForTransit transit);
|
|
||||||
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);
|
|
||||||
|
|
||||||
scoped_refptr<RefCountedTempDir> temp_dir_;
|
|
||||||
|
|
||||||
// Used to suppress callbacks after PdfConverter is deleted.
|
|
||||||
base::WeakPtr<PdfConverterImpl> converter_;
|
|
||||||
PdfRenderSettings settings_;
|
|
||||||
|
|
||||||
// Document loaded callback.
|
|
||||||
PdfConverter::StartCallback start_callback_;
|
|
||||||
|
|
||||||
// Process host for IPC.
|
|
||||||
base::WeakPtr<content::UtilityProcessHost> utility_process_host_;
|
|
||||||
|
|
||||||
// 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().
|
|
||||||
using GetPageCallbacks = std::queue<GetPageCallbackData>;
|
|
||||||
GetPageCallbacks get_page_callbacks_;
|
|
||||||
|
|
||||||
const scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(PdfConverterUtilityProcessHostClient);
|
|
||||||
};
|
|
||||||
|
|
||||||
std::unique_ptr<MetafilePlayer>
|
|
||||||
PdfConverterUtilityProcessHostClient::GetFileFromTemp(
|
|
||||||
ScopedTempFile temp_file) {
|
|
||||||
if (settings_.mode == PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2 ||
|
|
||||||
settings_.mode == PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3) {
|
|
||||||
return std::make_unique<PostScriptMetaFile>(temp_dir_,
|
|
||||||
std::move(temp_file));
|
|
||||||
}
|
|
||||||
return std::make_unique<LazyEmf>(temp_dir_, std::move(temp_file));
|
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
|
||||||
const StartCallback& start_callback);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
void Start(
|
|
||||||
const scoped_refptr<PdfConverterUtilityProcessHostClient>& utility_client,
|
|
||||||
const scoped_refptr<base::RefCountedMemory>& data,
|
|
||||||
const StartCallback& start_callback);
|
|
||||||
|
|
||||||
private:
|
|
||||||
scoped_refptr<PdfConverterUtilityProcessHostClient> utility_client_;
|
|
||||||
|
|
||||||
base::WeakPtrFactory<PdfConverterImpl> weak_ptr_factory_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(PdfConverterImpl);
|
|
||||||
};
|
|
||||||
|
|
||||||
ScopedTempFile CreateTempFile(scoped_refptr<RefCountedTempDir>* temp_dir) {
|
|
||||||
if (!temp_dir->get())
|
|
||||||
*temp_dir = base::MakeRefCounted<RefCountedTempDir>();
|
|
||||||
ScopedTempFile file;
|
|
||||||
if (!(*temp_dir)->IsValid())
|
|
||||||
return file;
|
|
||||||
base::FilePath path;
|
|
||||||
if (!base::CreateTemporaryFileInDir((*temp_dir)->GetPath(), &path)) {
|
|
||||||
PLOG(ERROR) << "Failed to create file in "
|
|
||||||
<< (*temp_dir)->GetPath().value();
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
file = std::make_unique<TempFile>(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->file().IsValid()) {
|
|
||||||
PLOG(ERROR) << "Failed to create " << path.value();
|
|
||||||
file.reset();
|
|
||||||
}
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopedTempFile CreateTempPdfFile(
|
|
||||||
const scoped_refptr<base::RefCountedMemory>& data,
|
|
||||||
scoped_refptr<RefCountedTempDir>* temp_dir) {
|
|
||||||
ScopedTempFile pdf_file = CreateTempFile(temp_dir);
|
|
||||||
if (!pdf_file || static_cast<int>(data->size()) !=
|
|
||||||
pdf_file->file().WriteAtCurrentPos(
|
|
||||||
data->front_as<char>(), data->size())) {
|
|
||||||
pdf_file.reset();
|
|
||||||
return pdf_file;
|
|
||||||
}
|
|
||||||
pdf_file->file().Seek(base::File::FROM_BEGIN, 0);
|
|
||||||
return pdf_file;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LazyEmf::SafePlayback(HDC hdc) const {
|
|
||||||
Emf emf;
|
|
||||||
bool result = LoadEmf(&emf) && emf.SafePlayback(hdc);
|
|
||||||
// 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.
|
|
||||||
Close();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LazyEmf::GetDataAsVector(std::vector<char>* buffer) const {
|
|
||||||
NOTREACHED();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LazyEmf::SaveTo(base::File* file) const {
|
|
||||||
Emf emf;
|
|
||||||
return LoadEmf(&emf) && emf.SaveTo(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LazyEmf::Close() const {
|
|
||||||
file_.reset();
|
|
||||||
temp_dir_ = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LazyEmf::LoadEmf(Emf* emf) const {
|
|
||||||
file_->file().Seek(base::File::FROM_BEGIN, 0);
|
|
||||||
int64_t size = file_->file().GetLength();
|
|
||||||
if (size <= 0)
|
|
||||||
return false;
|
|
||||||
std::vector<char> data(size);
|
|
||||||
if (file_->file().ReadAtCurrentPos(data.data(), data.size()) != size)
|
|
||||||
return false;
|
|
||||||
return emf->InitFromData(data.data(), data.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
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),
|
|
||||||
blocking_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
|
|
||||||
{base::MayBlock(), base::TaskPriority::USER_VISIBLE,
|
|
||||||
base::TaskShutdownBehavior::BLOCK_SHUTDOWN})) {}
|
|
||||||
|
|
||||||
PdfConverterUtilityProcessHostClient::~PdfConverterUtilityProcessHostClient() {}
|
|
||||||
|
|
||||||
void PdfConverterUtilityProcessHostClient::Start(
|
|
||||||
const scoped_refptr<base::RefCountedMemory>& data,
|
|
||||||
const PdfConverter::StartCallback& start_callback) {
|
|
||||||
CHECK(false) << "Printing doesn't work yet.";
|
|
||||||
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
|
|
||||||
BrowserThread::PostTask(
|
|
||||||
BrowserThread::IO, FROM_HERE,
|
|
||||||
base::Bind(&PdfConverterUtilityProcessHostClient::Start, this, data,
|
|
||||||
start_callback));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store callback before any OnFailed() call to make it called on failure.
|
|
||||||
start_callback_ = start_callback;
|
|
||||||
|
|
||||||
// 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::ThreadTaskRunnerHandle::Get())
|
|
||||||
->AsWeakPtr();
|
|
||||||
*/
|
|
||||||
utility_process_host_ = nullptr;
|
|
||||||
utility_process_host_->SetName(GetName());
|
|
||||||
|
|
||||||
base::PostTaskAndReplyWithResult(
|
|
||||||
blocking_task_runner_.get(), FROM_HERE,
|
|
||||||
base::Bind(&CreateTempPdfFile, data, &temp_dir_),
|
|
||||||
base::Bind(&PdfConverterUtilityProcessHostClient::OnTempPdfReady, this));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PdfConverterUtilityProcessHostClient::OnTempPdfReady(ScopedTempFile pdf) {
|
|
||||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
|
||||||
if (!utility_process_host_ || !pdf)
|
|
||||||
return OnFailed();
|
|
||||||
// Should reply with OnPageCount().
|
|
||||||
SendStartMessage(
|
|
||||||
IPC::GetPlatformFileForTransit(pdf->file().GetPlatformFile(), false));
|
|
||||||
}
|
|
||||||
|
|
||||||
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(&PdfConverterImpl::RunCallback, converter_,
|
|
||||||
base::Bind(start_callback_, page_count)));
|
|
||||||
start_callback_.Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PdfConverterUtilityProcessHostClient::GetPage(
|
|
||||||
int page_number,
|
|
||||||
const PdfConverter::GetPageCallback& get_page_callback) {
|
|
||||||
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
|
|
||||||
BrowserThread::PostTask(
|
|
||||||
BrowserThread::IO, FROM_HERE,
|
|
||||||
base::Bind(&PdfConverterUtilityProcessHostClient::GetPage, this,
|
|
||||||
page_number, get_page_callback));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store callback before any OnFailed() call to make it called on failure.
|
|
||||||
get_page_callbacks_.push(GetPageCallbackData(page_number, get_page_callback));
|
|
||||||
|
|
||||||
if (!utility_process_host_)
|
|
||||||
return OnFailed();
|
|
||||||
|
|
||||||
base::PostTaskAndReplyWithResult(
|
|
||||||
blocking_task_runner_.get(), FROM_HERE,
|
|
||||||
base::Bind(&CreateTempFile, &temp_dir_),
|
|
||||||
base::Bind(&PdfConverterUtilityProcessHostClient::OnTempFileReady, this,
|
|
||||||
&get_page_callbacks_.back()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PdfConverterUtilityProcessHostClient::OnTempFileReady(
|
|
||||||
GetPageCallbackData* callback_data,
|
|
||||||
ScopedTempFile temp_file) {
|
|
||||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
|
||||||
if (!utility_process_host_ || !temp_file)
|
|
||||||
return OnFailed();
|
|
||||||
IPC::PlatformFileForTransit transit = IPC::GetPlatformFileForTransit(
|
|
||||||
temp_file->file().GetPlatformFile(), false);
|
|
||||||
callback_data->set_file(std::move(temp_file));
|
|
||||||
// Should reply with OnPageDone().
|
|
||||||
SendGetPageMessage(callback_data->page_number(), transit);
|
|
||||||
}
|
|
||||||
|
|
||||||
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> file;
|
|
||||||
|
|
||||||
if (success) {
|
|
||||||
ScopedTempFile temp_file = data.TakeFile();
|
|
||||||
if (!temp_file) // Unexpected message from utility process.
|
|
||||||
return OnFailed();
|
|
||||||
file = GetFileFromTemp(std::move(temp_file));
|
|
||||||
}
|
|
||||||
|
|
||||||
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 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_)
|
|
||||||
#if 1
|
|
||||||
CHECK(false) << "Printing is broken.";
|
|
||||||
#else
|
|
||||||
return utility_process_host_->Send(msg);
|
|
||||||
#endif
|
|
||||||
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
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PdfConverterUtilityProcessHostClient::OnMessageReceived(
|
|
||||||
const IPC::Message& message) {
|
|
||||||
bool handled = true;
|
|
||||||
IPC_BEGIN_MESSAGE_MAP(PdfConverterUtilityProcessHostClient, message)
|
|
||||||
IPC_MESSAGE_HANDLER(
|
|
||||||
ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount, OnPageCount)
|
|
||||||
IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone,
|
|
||||||
OnPageDone)
|
|
||||||
#if 0
|
|
||||||
IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_PreCacheFontCharacters,
|
|
||||||
OnPreCacheFontCharacters)
|
|
||||||
#endif
|
|
||||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
|
||||||
IPC_END_MESSAGE_MAP()
|
|
||||||
return handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
base::string16 PdfConverterUtilityProcessHostClient::GetName() const {
|
|
||||||
return L"ChromeUtilityProcessPDFConvertor";
|
|
||||||
}
|
|
||||||
|
|
||||||
void PdfConverterUtilityProcessHostClient::SendGetPageMessage(
|
|
||||||
int page_number,
|
|
||||||
IPC::PlatformFileForTransit transit) {
|
|
||||||
Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage(page_number,
|
|
||||||
transit));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PdfConverterUtilityProcessHostClient::SendStartMessage(
|
|
||||||
IPC::PlatformFileForTransit transit) {
|
|
||||||
Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles(transit, settings_));
|
|
||||||
}
|
|
||||||
|
|
||||||
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 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 PdfConverterImpl::GetPage(int page_number,
|
|
||||||
const GetPageCallback& get_page_callback) {
|
|
||||||
utility_client_->GetPage(page_number, get_page_callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PdfConverterImpl::RunCallback(const base::Closure& callback) {
|
|
||||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
|
||||||
callback.Run();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
PdfConverter::~PdfConverter() {}
|
|
||||||
|
|
||||||
// static
|
|
||||||
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 =
|
|
||||||
std::make_unique<PdfConverterImpl>();
|
|
||||||
converter->Start(new PdfConverterUtilityProcessHostClient(
|
|
||||||
converter->GetWeakPtr(), conversion_settings),
|
|
||||||
data, start_callback);
|
|
||||||
return std::move(converter);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace printing
|
|
|
@ -1,43 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#ifndef CHROME_BROWSER_PRINTING_PDF_TO_EMF_CONVERTER_H_
|
|
||||||
#define CHROME_BROWSER_PRINTING_PDF_TO_EMF_CONVERTER_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "base/callback.h"
|
|
||||||
#include "base/memory/ref_counted_memory.h"
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
class MetafilePlayer;
|
|
||||||
struct PdfRenderSettings;
|
|
||||||
|
|
||||||
class PdfConverter {
|
|
||||||
public:
|
|
||||||
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.
|
|
||||||
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.
|
|
||||||
// Calls |get_page_callback| after conversion. |emf| of callback in not NULL
|
|
||||||
// if conversion succeeded.
|
|
||||||
virtual void GetPage(int page_number,
|
|
||||||
const GetPageCallback& get_page_callback) = 0;
|
|
||||||
};
|
|
||||||
} // namespace printing
|
|
||||||
|
|
||||||
#endif // CHROME_BROWSER_PRINTING_PDF_TO_EMF_CONVERTER_H_
|
|
|
@ -1,468 +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 "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/message_loop/message_loop.h"
|
|
||||||
#include "base/run_loop.h"
|
|
||||||
#include "base/single_thread_task_runner.h"
|
|
||||||
#include "base/task_scheduler/post_task.h"
|
|
||||||
#include "base/threading/thread_restrictions.h"
|
|
||||||
#include "base/threading/thread_task_runner_handle.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/notification_service.h"
|
|
||||||
#include "printing/printed_document.h"
|
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
#include "chrome/browser/printing/pdf_to_emf_converter.h"
|
|
||||||
#include "printing/metafile.h"
|
|
||||||
#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<PrintJobWorkerOwner>& owner,
|
|
||||||
const base::Closure& callback) {
|
|
||||||
callback.Run();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
PrintJob::PrintJob()
|
|
||||||
: is_job_pending_(false), is_canceling_(false), quit_factory_(this) {
|
|
||||||
DCHECK(base::MessageLoopForUI::IsCurrent());
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintJob::~PrintJob() {
|
|
||||||
// The job should be finished (or at least canceled) when it is destroyed.
|
|
||||||
DCHECK(!is_job_pending_);
|
|
||||||
DCHECK(!is_canceling_);
|
|
||||||
DCHECK(!worker_ || !worker_->IsRunning());
|
|
||||||
DCHECK(RunsTasksInCurrentSequence());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJob::Initialize(PrintJobWorkerOwner* job,
|
|
||||||
const base::string16& name,
|
|
||||||
int page_count) {
|
|
||||||
DCHECK(!worker_);
|
|
||||||
DCHECK(!is_job_pending_);
|
|
||||||
DCHECK(!is_canceling_);
|
|
||||||
DCHECK(!document_.get());
|
|
||||||
worker_ = job->DetachWorker(this);
|
|
||||||
settings_ = job->settings();
|
|
||||||
|
|
||||||
PrintedDocument* new_doc =
|
|
||||||
new PrintedDocument(settings_, name, job->cookie());
|
|
||||||
new_doc->set_page_count(page_count);
|
|
||||||
UpdatePrintedDocument(new_doc);
|
|
||||||
|
|
||||||
// Don't forget to register to our own messages.
|
|
||||||
registrar_.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
|
|
||||||
content::Source<PrintJob>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJob::Observe(int type,
|
|
||||||
const content::NotificationSource& source,
|
|
||||||
const content::NotificationDetails& details) {
|
|
||||||
DCHECK(RunsTasksInCurrentSequence());
|
|
||||||
DCHECK_EQ(chrome::NOTIFICATION_PRINT_JOB_EVENT, type);
|
|
||||||
|
|
||||||
OnNotifyPrintJobEvent(*content::Details<JobEventDetails>(details).ptr());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJob::GetSettingsDone(const PrintSettings& new_settings,
|
|
||||||
PrintingContext::Result result) {
|
|
||||||
NOTREACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<PrintJobWorker> PrintJob::DetachWorker(
|
|
||||||
PrintJobWorkerOwner* new_owner) {
|
|
||||||
NOTREACHED();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
const PrintSettings& PrintJob::settings() const {
|
|
||||||
return settings_;
|
|
||||||
}
|
|
||||||
|
|
||||||
int PrintJob::cookie() const {
|
|
||||||
// Always use an invalid cookie in this case.
|
|
||||||
if (!document_.get())
|
|
||||||
return 0;
|
|
||||||
return document_->cookie();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJob::StartPrinting() {
|
|
||||||
DCHECK(RunsTasksInCurrentSequence());
|
|
||||||
if (!worker_->IsRunning() || is_job_pending_) {
|
|
||||||
NOTREACHED();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Real work is done in PrintJobWorker::StartPrinting().
|
|
||||||
worker_->PostTask(FROM_HERE,
|
|
||||||
base::Bind(&HoldRefCallback, WrapRefCounted(this),
|
|
||||||
base::Bind(&PrintJobWorker::StartPrinting,
|
|
||||||
base::Unretained(worker_.get()),
|
|
||||||
base::RetainedRef(document_))));
|
|
||||||
// Set the flag right now.
|
|
||||||
is_job_pending_ = true;
|
|
||||||
|
|
||||||
// Tell everyone!
|
|
||||||
scoped_refptr<JobEventDetails> details(
|
|
||||||
new JobEventDetails(JobEventDetails::NEW_DOC, 0, document_.get()));
|
|
||||||
content::NotificationService::current()->Notify(
|
|
||||||
chrome::NOTIFICATION_PRINT_JOB_EVENT, content::Source<PrintJob>(this),
|
|
||||||
content::Details<JobEventDetails>(details.get()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJob::Stop() {
|
|
||||||
DCHECK(RunsTasksInCurrentSequence());
|
|
||||||
|
|
||||||
if (quit_factory_.HasWeakPtrs()) {
|
|
||||||
// In case we're running a nested message loop to wait for a job to finish,
|
|
||||||
// and we finished before the timeout, quit the nested loop right away.
|
|
||||||
Quit();
|
|
||||||
quit_factory_.InvalidateWeakPtrs();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Be sure to live long enough.
|
|
||||||
scoped_refptr<PrintJob> handle(this);
|
|
||||||
|
|
||||||
if (worker_->IsRunning()) {
|
|
||||||
ControlledWorkerShutdown();
|
|
||||||
} else {
|
|
||||||
// Flush the cached document.
|
|
||||||
is_job_pending_ = false;
|
|
||||||
UpdatePrintedDocument(nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJob::Cancel() {
|
|
||||||
if (is_canceling_)
|
|
||||||
return;
|
|
||||||
is_canceling_ = true;
|
|
||||||
|
|
||||||
// Be sure to live long enough.
|
|
||||||
scoped_refptr<PrintJob> handle(this);
|
|
||||||
|
|
||||||
DCHECK(RunsTasksInCurrentSequence());
|
|
||||||
if (worker_ && worker_->IsRunning()) {
|
|
||||||
// Call this right now so it renders the context invalid. Do not use
|
|
||||||
// InvokeLater since it would take too much time.
|
|
||||||
worker_->Cancel();
|
|
||||||
}
|
|
||||||
// Make sure a Cancel() is broadcast.
|
|
||||||
scoped_refptr<JobEventDetails> details(
|
|
||||||
new JobEventDetails(JobEventDetails::FAILED, 0, nullptr));
|
|
||||||
content::NotificationService::current()->Notify(
|
|
||||||
chrome::NOTIFICATION_PRINT_JOB_EVENT, content::Source<PrintJob>(this),
|
|
||||||
content::Details<JobEventDetails>(details.get()));
|
|
||||||
Stop();
|
|
||||||
is_canceling_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PrintJob::FlushJob(base::TimeDelta timeout) {
|
|
||||||
// Make sure the object outlive this message loop.
|
|
||||||
scoped_refptr<PrintJob> handle(this);
|
|
||||||
|
|
||||||
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
|
|
||||||
FROM_HERE, base::Bind(&PrintJob::Quit, quit_factory_.GetWeakPtr()),
|
|
||||||
timeout);
|
|
||||||
|
|
||||||
base::MessageLoop::ScopedNestableTaskAllower allow;
|
|
||||||
base::RunLoop().Run();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PrintJob::is_job_pending() const {
|
|
||||||
return is_job_pending_;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintedDocument* PrintJob::document() const {
|
|
||||||
return document_.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
class PrintJob::PdfConversionState {
|
|
||||||
public:
|
|
||||||
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) {}
|
|
||||||
|
|
||||||
void Start(const scoped_refptr<base::RefCountedMemory>& data,
|
|
||||||
const PdfRenderSettings& conversion_settings,
|
|
||||||
const PdfConverter::StartCallback& start_callback) {
|
|
||||||
converter_ = PdfConverter::StartPdfConverter(data, conversion_settings,
|
|
||||||
start_callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetMorePages(const PdfConverter::GetPageCallback& get_page_callback) {
|
|
||||||
const int kMaxNumberOfTempFilesPerDocument = 3;
|
|
||||||
while (pages_in_progress_ < kMaxNumberOfTempFilesPerDocument &&
|
|
||||||
current_page_ < page_count_) {
|
|
||||||
++pages_in_progress_;
|
|
||||||
converter_->GetPage(current_page_++, 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.
|
|
||||||
if (!pages_in_progress_ && current_page_ >= page_count_)
|
|
||||||
converter_.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_page_count(int page_count) { page_count_ = page_count; }
|
|
||||||
gfx::Size page_size() const { return page_size_; }
|
|
||||||
gfx::Rect content_area() const { return content_area_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
int page_count_;
|
|
||||||
int current_page_;
|
|
||||||
int pages_in_progress_;
|
|
||||||
gfx::Size page_size_;
|
|
||||||
gfx::Rect content_area_;
|
|
||||||
std::unique_ptr<PdfConverter> 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,
|
|
||||||
bool print_text_with_gdi) {
|
|
||||||
DCHECK(!pdf_conversion_state_);
|
|
||||||
pdf_conversion_state_ =
|
|
||||||
std::make_unique<PdfConversionState>(page_size, content_area);
|
|
||||||
const int kPrinterDpi = settings().dpi();
|
|
||||||
PdfRenderSettings settings(
|
|
||||||
content_area, gfx::Point(0, 0), gfx::Size(kPrinterDpi, kPrinterDpi),
|
|
||||||
/*autorotate=*/true, settings_.color() == COLOR,
|
|
||||||
print_text_with_gdi ? PdfRenderSettings::Mode::GDI_TEXT
|
|
||||||
: PdfRenderSettings::Mode::NORMAL);
|
|
||||||
pdf_conversion_state_->Start(
|
|
||||||
bytes, settings, base::Bind(&PrintJob::OnPdfConversionStarted, this));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJob::OnPdfConversionStarted(int page_count) {
|
|
||||||
if (page_count <= 0) {
|
|
||||||
pdf_conversion_state_.reset();
|
|
||||||
Cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pdf_conversion_state_->set_page_count(page_count);
|
|
||||||
pdf_conversion_state_->GetMorePages(
|
|
||||||
base::Bind(&PrintJob::OnPdfPageConverted, this));
|
|
||||||
}
|
|
||||||
|
|
||||||
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_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(metafile),
|
|
||||||
scale_factor, pdf_conversion_state_->page_size(),
|
|
||||||
pdf_conversion_state_->content_area());
|
|
||||||
|
|
||||||
pdf_conversion_state_->GetMorePages(
|
|
||||||
base::Bind(&PrintJob::OnPdfPageConverted, this));
|
|
||||||
}
|
|
||||||
|
|
||||||
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_ =
|
|
||||||
std::make_unique<PdfConversionState>(gfx::Size(), gfx::Rect());
|
|
||||||
const int kPrinterDpi = settings().dpi();
|
|
||||||
PdfRenderSettings settings(
|
|
||||||
content_area, physical_offsets, gfx::Size(kPrinterDpi, kPrinterDpi),
|
|
||||||
true /* autorotate? */, settings_.color() == COLOR,
|
|
||||||
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)
|
|
||||||
return;
|
|
||||||
|
|
||||||
document_ = new_document;
|
|
||||||
|
|
||||||
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, WrapRefCounted(this),
|
|
||||||
base::Bind(&PrintJobWorker::OnDocumentChanged,
|
|
||||||
base::Unretained(worker_.get()),
|
|
||||||
base::RetainedRef(document_))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJob::OnNotifyPrintJobEvent(const JobEventDetails& event_details) {
|
|
||||||
switch (event_details.type()) {
|
|
||||||
case JobEventDetails::FAILED: {
|
|
||||||
settings_.Clear();
|
|
||||||
// No need to cancel since the worker already canceled itself.
|
|
||||||
Stop();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case JobEventDetails::USER_INIT_DONE:
|
|
||||||
case JobEventDetails::DEFAULT_INIT_DONE:
|
|
||||||
case JobEventDetails::USER_INIT_CANCELED: {
|
|
||||||
DCHECK_EQ(event_details.document(), document_.get());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case JobEventDetails::NEW_DOC:
|
|
||||||
case JobEventDetails::NEW_PAGE:
|
|
||||||
case JobEventDetails::JOB_DONE:
|
|
||||||
case JobEventDetails::ALL_PAGES_REQUESTED: {
|
|
||||||
// Don't care.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case JobEventDetails::DOC_DONE: {
|
|
||||||
// This will call Stop() and broadcast a JOB_DONE message.
|
|
||||||
base::ThreadTaskRunnerHandle::Get()->PostTask(
|
|
||||||
FROM_HERE, base::Bind(&PrintJob::OnDocumentDone, this));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case JobEventDetails::PAGE_DONE:
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
if (pdf_conversion_state_) {
|
|
||||||
pdf_conversion_state_->OnPageProcessed(
|
|
||||||
base::Bind(&PrintJob::OnPdfPageConverted, this));
|
|
||||||
}
|
|
||||||
#endif // defined(OS_WIN)
|
|
||||||
break;
|
|
||||||
default: {
|
|
||||||
NOTREACHED();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJob::OnDocumentDone() {
|
|
||||||
// Be sure to live long enough. The instance could be destroyed by the
|
|
||||||
// JOB_DONE broadcast.
|
|
||||||
scoped_refptr<PrintJob> handle(this);
|
|
||||||
|
|
||||||
// Stop the worker thread.
|
|
||||||
Stop();
|
|
||||||
|
|
||||||
scoped_refptr<JobEventDetails> details(
|
|
||||||
new JobEventDetails(JobEventDetails::JOB_DONE, 0, document_.get()));
|
|
||||||
content::NotificationService::current()->Notify(
|
|
||||||
chrome::NOTIFICATION_PRINT_JOB_EVENT, content::Source<PrintJob>(this),
|
|
||||||
content::Details<JobEventDetails>(details.get()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJob::ControlledWorkerShutdown() {
|
|
||||||
DCHECK(RunsTasksInCurrentSequence());
|
|
||||||
|
|
||||||
// The deadlock this code works around is specific to window messaging on
|
|
||||||
// Windows, so we aren't likely to need it on any other platforms.
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
// We could easily get into a deadlock case if worker_->Stop() is used; the
|
|
||||||
// printer driver created a window as a child of the browser window. By
|
|
||||||
// canceling the job, the printer driver initiated dialog box is destroyed,
|
|
||||||
// which sends a blocking message to its parent window. If the browser window
|
|
||||||
// thread is not processing messages, a deadlock occurs.
|
|
||||||
//
|
|
||||||
// This function ensures that the dialog box will be destroyed in a timely
|
|
||||||
// manner by the mere fact that the thread will terminate. So the potential
|
|
||||||
// deadlock is eliminated.
|
|
||||||
worker_->StopSoon();
|
|
||||||
|
|
||||||
// Delay shutdown until the worker terminates. We want this code path
|
|
||||||
// to wait on the thread to quit before continuing.
|
|
||||||
if (worker_->IsRunning()) {
|
|
||||||
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
|
|
||||||
FROM_HERE, base::Bind(&PrintJob::ControlledWorkerShutdown, this),
|
|
||||||
base::TimeDelta::FromMilliseconds(100));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Now make sure the thread object is cleaned up. Do this on a worker
|
|
||||||
// thread because it may block.
|
|
||||||
base::PostTaskAndReply(
|
|
||||||
FROM_HERE,
|
|
||||||
base::Bind(&PrintJobWorker::Stop, base::Unretained(worker_.get())),
|
|
||||||
base::Bind(&PrintJob::HoldUntilStopIsCalled, this));
|
|
||||||
|
|
||||||
is_job_pending_ = false;
|
|
||||||
registrar_.RemoveAll();
|
|
||||||
UpdatePrintedDocument(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJob::HoldUntilStopIsCalled() {}
|
|
||||||
|
|
||||||
void PrintJob::Quit() {
|
|
||||||
base::RunLoop::QuitCurrentWhenIdleDeprecated();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Takes settings_ ownership and will be deleted in the receiving thread.
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
JobEventDetails::JobEventDetails(Type type,
|
|
||||||
int job_id,
|
|
||||||
PrintedDocument* document,
|
|
||||||
PrintedPage* page)
|
|
||||||
: document_(document), page_(page), type_(type), job_id_(job_id) {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
JobEventDetails::JobEventDetails(Type type,
|
|
||||||
int job_id,
|
|
||||||
PrintedDocument* document)
|
|
||||||
: document_(document), type_(type), job_id_(job_id) {}
|
|
||||||
|
|
||||||
JobEventDetails::~JobEventDetails() {}
|
|
||||||
|
|
||||||
PrintedDocument* JobEventDetails::document() const {
|
|
||||||
return document_.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
PrintedPage* JobEventDetails::page() const {
|
|
||||||
return page_.get();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} // namespace printing
|
|
|
@ -1,246 +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 CHROME_BROWSER_PRINTING_PRINT_JOB_H_
|
|
||||||
#define CHROME_BROWSER_PRINTING_PRINT_JOB_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "base/macros.h"
|
|
||||||
#include "base/memory/weak_ptr.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"
|
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
#include "printing/printed_page_win.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace base {
|
|
||||||
class RefCountedMemory;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
class JobEventDetails;
|
|
||||||
class MetafilePlayer;
|
|
||||||
class PdfToEmfConverter;
|
|
||||||
class PrintJobWorker;
|
|
||||||
class PrintedDocument;
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
class PrintedPage;
|
|
||||||
#endif
|
|
||||||
class PrinterQuery;
|
|
||||||
|
|
||||||
// Manages the print work for a specific document. Talks to the printer through
|
|
||||||
// PrintingContext through PrintJobWorker. Hides access to PrintingContext in a
|
|
||||||
// worker thread so the caller never blocks. PrintJob will send notifications on
|
|
||||||
// any state change. While printing, the PrintJobManager instance keeps a
|
|
||||||
// reference to the job to be sure it is kept alive. All the code in this class
|
|
||||||
// runs in the UI thread.
|
|
||||||
class PrintJob : public PrintJobWorkerOwner,
|
|
||||||
public content::NotificationObserver {
|
|
||||||
public:
|
|
||||||
// Create a empty PrintJob. When initializing with this constructor,
|
|
||||||
// post-constructor initialization must be done with Initialize().
|
|
||||||
PrintJob();
|
|
||||||
|
|
||||||
// Grabs the ownership of the PrintJobWorker from another job, which is
|
|
||||||
// usually a PrinterQuery. Set the expected page count of the print job.
|
|
||||||
void Initialize(PrintJobWorkerOwner* job,
|
|
||||||
const base::string16& name,
|
|
||||||
int page_count);
|
|
||||||
|
|
||||||
// content::NotificationObserver implementation.
|
|
||||||
void Observe(int type,
|
|
||||||
const content::NotificationSource& source,
|
|
||||||
const content::NotificationDetails& details) override;
|
|
||||||
|
|
||||||
// PrintJobWorkerOwner implementation.
|
|
||||||
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.
|
|
||||||
void StartPrinting();
|
|
||||||
|
|
||||||
// Asks for the worker thread to finish its queued tasks and disconnects the
|
|
||||||
// delegate object. The PrintJobManager will remove its reference. This may
|
|
||||||
// have the side-effect of destroying the object if the caller doesn't have a
|
|
||||||
// handle to the object. Use PrintJob::is_stopped() to check whether the
|
|
||||||
// worker thread has actually stopped.
|
|
||||||
void Stop();
|
|
||||||
|
|
||||||
// Cancels printing job and stops the worker thread. Takes effect immediately.
|
|
||||||
void Cancel();
|
|
||||||
|
|
||||||
// Synchronously wait for the job to finish. It is mainly useful when the
|
|
||||||
// process is about to be shut down and we're waiting for the spooler to eat
|
|
||||||
// our data.
|
|
||||||
bool FlushJob(base::TimeDelta timeout);
|
|
||||||
|
|
||||||
// Returns true if the print job is pending, i.e. between a StartPrinting()
|
|
||||||
// and the end of the spooling.
|
|
||||||
bool is_job_pending() const;
|
|
||||||
|
|
||||||
// Access the current printed document. Warning: may be NULL.
|
|
||||||
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,
|
|
||||||
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:
|
|
||||||
~PrintJob() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Updates |document_| to a new instance.
|
|
||||||
void UpdatePrintedDocument(PrintedDocument* new_document);
|
|
||||||
|
|
||||||
// Processes a NOTIFY_PRINT_JOB_EVENT notification.
|
|
||||||
void OnNotifyPrintJobEvent(const JobEventDetails& event_details);
|
|
||||||
|
|
||||||
// Releases the worker thread by calling Stop(), then broadcasts a JOB_DONE
|
|
||||||
// notification.
|
|
||||||
void OnDocumentDone();
|
|
||||||
|
|
||||||
// Terminates the worker thread in a very controlled way, to work around any
|
|
||||||
// eventual deadlock.
|
|
||||||
void ControlledWorkerShutdown();
|
|
||||||
|
|
||||||
// Called at shutdown when running a nested message loop.
|
|
||||||
void Quit();
|
|
||||||
|
|
||||||
void HoldUntilStopIsCalled();
|
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
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_;
|
|
||||||
|
|
||||||
// All the UI is done in a worker thread because many Win32 print functions
|
|
||||||
// are blocking and enters a message loop without your consent. There is one
|
|
||||||
// worker thread per print job.
|
|
||||||
std::unique_ptr<PrintJobWorker> worker_;
|
|
||||||
|
|
||||||
// Cache of the print context settings for access in the UI thread.
|
|
||||||
PrintSettings settings_;
|
|
||||||
|
|
||||||
// The printed document.
|
|
||||||
scoped_refptr<PrintedDocument> document_;
|
|
||||||
|
|
||||||
// Is the worker thread printing.
|
|
||||||
bool is_job_pending_;
|
|
||||||
|
|
||||||
// Is Canceling? If so, try to not cause recursion if on FAILED notification,
|
|
||||||
// the notified calls Cancel() again.
|
|
||||||
bool is_canceling_;
|
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
class PdfConversionState;
|
|
||||||
std::unique_ptr<PdfConversionState> pdf_conversion_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_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(PrintJob);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Details for a NOTIFY_PRINT_JOB_EVENT notification. The members may be NULL.
|
|
||||||
class JobEventDetails : public base::RefCountedThreadSafe<JobEventDetails> {
|
|
||||||
public:
|
|
||||||
// Event type.
|
|
||||||
enum Type {
|
|
||||||
// Print... dialog box has been closed with OK button.
|
|
||||||
USER_INIT_DONE,
|
|
||||||
|
|
||||||
// Print... dialog box has been closed with CANCEL button.
|
|
||||||
USER_INIT_CANCELED,
|
|
||||||
|
|
||||||
// An automated initialization has been done, e.g. Init(false, NULL).
|
|
||||||
DEFAULT_INIT_DONE,
|
|
||||||
|
|
||||||
// A new document started printing.
|
|
||||||
NEW_DOC,
|
|
||||||
|
|
||||||
// A new page started printing.
|
|
||||||
NEW_PAGE,
|
|
||||||
|
|
||||||
// A page is done printing.
|
|
||||||
PAGE_DONE,
|
|
||||||
|
|
||||||
// A document is done printing. The worker thread is still alive. Warning:
|
|
||||||
// not a good moment to release the handle to PrintJob.
|
|
||||||
DOC_DONE,
|
|
||||||
|
|
||||||
// The worker thread is finished. A good moment to release the handle to
|
|
||||||
// PrintJob.
|
|
||||||
JOB_DONE,
|
|
||||||
|
|
||||||
// All missing pages have been requested.
|
|
||||||
ALL_PAGES_REQUESTED,
|
|
||||||
|
|
||||||
// An error occured. Printing is canceled.
|
|
||||||
FAILED,
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
JobEventDetails(Type type,
|
|
||||||
int job_id,
|
|
||||||
PrintedDocument* document,
|
|
||||||
PrintedPage* page);
|
|
||||||
#endif
|
|
||||||
JobEventDetails(Type type, int job_id, PrintedDocument* document);
|
|
||||||
|
|
||||||
// Getters.
|
|
||||||
PrintedDocument* document() const;
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
PrintedPage* page() const;
|
|
||||||
#endif
|
|
||||||
Type type() const { return type_; }
|
|
||||||
int job_id() const { return job_id_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class base::RefCountedThreadSafe<JobEventDetails>;
|
|
||||||
|
|
||||||
~JobEventDetails();
|
|
||||||
|
|
||||||
scoped_refptr<PrintedDocument> document_;
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
scoped_refptr<PrintedPage> page_;
|
|
||||||
#endif
|
|
||||||
const Type type_;
|
|
||||||
int job_id_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(JobEventDetails);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace printing
|
|
||||||
|
|
||||||
#endif // CHROME_BROWSER_PRINTING_PRINT_JOB_H_
|
|
|
@ -1,151 +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 "chrome/browser/printing/print_job_manager.h"
|
|
||||||
|
|
||||||
#include "chrome/browser/chrome_notification_types.h"
|
|
||||||
#include "chrome/browser/printing/print_job.h"
|
|
||||||
#include "chrome/browser/printing/printer_query.h"
|
|
||||||
#include "content/public/browser/browser_thread.h"
|
|
||||||
#include "content/public/browser/notification_service.h"
|
|
||||||
#include "printing/printed_document.h"
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
PrintQueriesQueue::PrintQueriesQueue() {}
|
|
||||||
|
|
||||||
PrintQueriesQueue::~PrintQueriesQueue() {
|
|
||||||
base::AutoLock lock(lock_);
|
|
||||||
queued_queries_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintQueriesQueue::QueuePrinterQuery(PrinterQuery* job) {
|
|
||||||
base::AutoLock lock(lock_);
|
|
||||||
DCHECK(job);
|
|
||||||
queued_queries_.push_back(WrapRefCounted(job));
|
|
||||||
DCHECK(job->is_valid());
|
|
||||||
}
|
|
||||||
|
|
||||||
scoped_refptr<PrinterQuery> PrintQueriesQueue::PopPrinterQuery(
|
|
||||||
int document_cookie) {
|
|
||||||
base::AutoLock lock(lock_);
|
|
||||||
for (PrinterQueries::iterator itr = queued_queries_.begin();
|
|
||||||
itr != queued_queries_.end(); ++itr) {
|
|
||||||
if ((*itr)->cookie() == document_cookie && !(*itr)->is_callback_pending()) {
|
|
||||||
scoped_refptr<PrinterQuery> current_query(*itr);
|
|
||||||
queued_queries_.erase(itr);
|
|
||||||
DCHECK(current_query->is_valid());
|
|
||||||
return current_query;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
scoped_refptr<PrinterQuery> PrintQueriesQueue::CreatePrinterQuery(
|
|
||||||
int render_process_id,
|
|
||||||
int render_frame_id) {
|
|
||||||
return WrapRefCounted(new PrinterQuery(render_process_id, render_frame_id));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintQueriesQueue::Shutdown() {
|
|
||||||
PrinterQueries queries_to_stop;
|
|
||||||
{
|
|
||||||
base::AutoLock lock(lock_);
|
|
||||||
queued_queries_.swap(queries_to_stop);
|
|
||||||
}
|
|
||||||
// Stop all pending queries, requests to generate print preview do not have
|
|
||||||
// corresponding PrintJob, so any pending preview requests are not covered
|
|
||||||
// by PrintJobManager::StopJobs and should be stopped explicitly.
|
|
||||||
for (PrinterQueries::iterator itr = queries_to_stop.begin();
|
|
||||||
itr != queries_to_stop.end(); ++itr) {
|
|
||||||
(*itr)->PostTask(FROM_HERE, base::Bind(&PrinterQuery::StopWorker, *itr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintJobManager::PrintJobManager() : is_shutdown_(false) {
|
|
||||||
registrar_.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
|
|
||||||
content::NotificationService::AllSources());
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintJobManager::~PrintJobManager() {}
|
|
||||||
|
|
||||||
scoped_refptr<PrintQueriesQueue> PrintJobManager::queue() {
|
|
||||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
|
||||||
if (!queue_.get())
|
|
||||||
queue_ = new PrintQueriesQueue();
|
|
||||||
return queue_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJobManager::Shutdown() {
|
|
||||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
|
||||||
DCHECK(!is_shutdown_);
|
|
||||||
is_shutdown_ = true;
|
|
||||||
registrar_.RemoveAll();
|
|
||||||
StopJobs(true);
|
|
||||||
if (queue_.get())
|
|
||||||
queue_->Shutdown();
|
|
||||||
queue_ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJobManager::StopJobs(bool wait_for_finish) {
|
|
||||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
|
||||||
// Copy the array since it can be modified in transit.
|
|
||||||
PrintJobs to_stop;
|
|
||||||
to_stop.swap(current_jobs_);
|
|
||||||
|
|
||||||
for (PrintJobs::const_iterator job = to_stop.begin(); job != to_stop.end();
|
|
||||||
++job) {
|
|
||||||
// Wait for two minutes for the print job to be spooled.
|
|
||||||
if (wait_for_finish)
|
|
||||||
(*job)->FlushJob(base::TimeDelta::FromMinutes(2));
|
|
||||||
(*job)->Stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJobManager::Observe(int type,
|
|
||||||
const content::NotificationSource& source,
|
|
||||||
const content::NotificationDetails& details) {
|
|
||||||
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(PrintJob* print_job,
|
|
||||||
const JobEventDetails& event_details) {
|
|
||||||
switch (event_details.type()) {
|
|
||||||
case JobEventDetails::NEW_DOC: {
|
|
||||||
DCHECK(current_jobs_.end() == current_jobs_.find(print_job));
|
|
||||||
// Causes a AddRef().
|
|
||||||
current_jobs_.insert(print_job);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case JobEventDetails::JOB_DONE: {
|
|
||||||
DCHECK(current_jobs_.end() != current_jobs_.find(print_job));
|
|
||||||
current_jobs_.erase(print_job);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case JobEventDetails::FAILED: {
|
|
||||||
current_jobs_.erase(print_job);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case JobEventDetails::USER_INIT_DONE:
|
|
||||||
case JobEventDetails::USER_INIT_CANCELED:
|
|
||||||
case JobEventDetails::DEFAULT_INIT_DONE:
|
|
||||||
case JobEventDetails::NEW_PAGE:
|
|
||||||
case JobEventDetails::PAGE_DONE:
|
|
||||||
case JobEventDetails::DOC_DONE:
|
|
||||||
case JobEventDetails::ALL_PAGES_REQUESTED: {
|
|
||||||
// Don't care.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
NOTREACHED();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace printing
|
|
|
@ -1,100 +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 CHROME_BROWSER_PRINTING_PRINT_JOB_MANAGER_H_
|
|
||||||
#define CHROME_BROWSER_PRINTING_PRINT_JOB_MANAGER_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <set>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "base/logging.h"
|
|
||||||
#include "base/macros.h"
|
|
||||||
#include "base/memory/ref_counted.h"
|
|
||||||
#include "base/synchronization/lock.h"
|
|
||||||
#include "content/public/browser/notification_observer.h"
|
|
||||||
#include "content/public/browser/notification_registrar.h"
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
class JobEventDetails;
|
|
||||||
class PrintJob;
|
|
||||||
class PrinterQuery;
|
|
||||||
|
|
||||||
class PrintQueriesQueue : public base::RefCountedThreadSafe<PrintQueriesQueue> {
|
|
||||||
public:
|
|
||||||
PrintQueriesQueue();
|
|
||||||
|
|
||||||
// Queues a semi-initialized worker thread. Can be called from any thread.
|
|
||||||
// Current use case is queuing from the I/O thread.
|
|
||||||
// TODO(maruel): Have them vanish after a timeout (~5 minutes?)
|
|
||||||
void QueuePrinterQuery(PrinterQuery* job);
|
|
||||||
|
|
||||||
// Pops a queued PrintJobWorkerOwner object that was previously queued or
|
|
||||||
// create new one. Can be called from any thread.
|
|
||||||
scoped_refptr<PrinterQuery> PopPrinterQuery(int document_cookie);
|
|
||||||
|
|
||||||
// Creates new query.
|
|
||||||
scoped_refptr<PrinterQuery> CreatePrinterQuery(int render_process_id,
|
|
||||||
int render_frame_id);
|
|
||||||
|
|
||||||
void Shutdown();
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class base::RefCountedThreadSafe<PrintQueriesQueue>;
|
|
||||||
typedef std::vector<scoped_refptr<PrinterQuery>> PrinterQueries;
|
|
||||||
|
|
||||||
virtual ~PrintQueriesQueue();
|
|
||||||
|
|
||||||
// Used to serialize access to queued_workers_.
|
|
||||||
base::Lock lock_;
|
|
||||||
|
|
||||||
PrinterQueries queued_queries_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(PrintQueriesQueue);
|
|
||||||
};
|
|
||||||
|
|
||||||
class PrintJobManager : public content::NotificationObserver {
|
|
||||||
public:
|
|
||||||
PrintJobManager();
|
|
||||||
~PrintJobManager() override;
|
|
||||||
|
|
||||||
// On browser quit, we should wait to have the print job finished.
|
|
||||||
void Shutdown();
|
|
||||||
|
|
||||||
// content::NotificationObserver
|
|
||||||
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.
|
|
||||||
scoped_refptr<PrintQueriesQueue> queue();
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef std::set<scoped_refptr<PrintJob>> PrintJobs;
|
|
||||||
|
|
||||||
// Processes a NOTIFY_PRINT_JOB_EVENT notification.
|
|
||||||
void OnPrintJobEvent(PrintJob* print_job,
|
|
||||||
const JobEventDetails& event_details);
|
|
||||||
|
|
||||||
// Stops all printing jobs. If wait_for_finish is true, tries to give jobs
|
|
||||||
// a chance to complete before stopping them.
|
|
||||||
void StopJobs(bool wait_for_finish);
|
|
||||||
|
|
||||||
content::NotificationRegistrar registrar_;
|
|
||||||
|
|
||||||
// Current print jobs that are active.
|
|
||||||
PrintJobs current_jobs_;
|
|
||||||
|
|
||||||
scoped_refptr<PrintQueriesQueue> queue_;
|
|
||||||
|
|
||||||
bool is_shutdown_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(PrintJobManager);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace printing
|
|
||||||
|
|
||||||
#endif // CHROME_BROWSER_PRINTING_PRINT_JOB_MANAGER_H_
|
|
|
@ -1,558 +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 "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/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_frame_host.h"
|
|
||||||
#include "content/public/browser/web_contents.h"
|
|
||||||
#include "printing/print_job_constants.h"
|
|
||||||
#include "printing/printed_document.h"
|
|
||||||
#include "printing/printing_utils.h"
|
|
||||||
#include "ui/base/l10n/l10n_util.h"
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cmath>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "base/strings/string_number_conversions.h"
|
|
||||||
#include "base/strings/utf_string_conversions.h"
|
|
||||||
#include "base/time/time.h"
|
|
||||||
#include "printing/page_size_margins.h"
|
|
||||||
#include "printing/print_job_constants.h"
|
|
||||||
#include "printing/print_settings.h"
|
|
||||||
#include "printing/units.h"
|
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
#include "printing/printed_page_win.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using content::BrowserThread;
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
// Helper function to ensure |owner| is valid until at least |callback| returns.
|
|
||||||
void HoldRefCallback(const scoped_refptr<PrintJobWorkerOwner>& owner,
|
|
||||||
base::OnceClosure callback) {
|
|
||||||
std::move(callback).Run();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetCustomMarginsToJobSettings(const PageSizeMargins& page_size_margins,
|
|
||||||
base::DictionaryValue* settings) {
|
|
||||||
std::unique_ptr<base::DictionaryValue> custom_margins(
|
|
||||||
new base::DictionaryValue());
|
|
||||||
custom_margins->SetDouble(kSettingMarginTop, page_size_margins.margin_top);
|
|
||||||
custom_margins->SetDouble(kSettingMarginBottom,
|
|
||||||
page_size_margins.margin_bottom);
|
|
||||||
custom_margins->SetDouble(kSettingMarginLeft, page_size_margins.margin_left);
|
|
||||||
custom_margins->SetDouble(kSettingMarginRight,
|
|
||||||
page_size_margins.margin_right);
|
|
||||||
settings->Set(kSettingMarginsCustom, std::move(custom_margins));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintSettingsToJobSettings(const PrintSettings& settings,
|
|
||||||
base::DictionaryValue* job_settings) {
|
|
||||||
// header footer
|
|
||||||
job_settings->SetBoolean(kSettingHeaderFooterEnabled,
|
|
||||||
settings.display_header_footer());
|
|
||||||
job_settings->SetString(kSettingHeaderFooterTitle, settings.title());
|
|
||||||
job_settings->SetString(kSettingHeaderFooterURL, settings.url());
|
|
||||||
|
|
||||||
// bg
|
|
||||||
job_settings->SetBoolean(kSettingShouldPrintBackgrounds,
|
|
||||||
settings.should_print_backgrounds());
|
|
||||||
job_settings->SetBoolean(kSettingShouldPrintSelectionOnly,
|
|
||||||
settings.selection_only());
|
|
||||||
|
|
||||||
// margin
|
|
||||||
auto margin_type = settings.margin_type();
|
|
||||||
job_settings->SetInteger(kSettingMarginsType, settings.margin_type());
|
|
||||||
if (margin_type == CUSTOM_MARGINS) {
|
|
||||||
const auto& margins_in_points =
|
|
||||||
settings.requested_custom_margins_in_points();
|
|
||||||
|
|
||||||
PageSizeMargins page_size_margins;
|
|
||||||
|
|
||||||
page_size_margins.margin_top = margins_in_points.top;
|
|
||||||
page_size_margins.margin_bottom = margins_in_points.bottom;
|
|
||||||
page_size_margins.margin_left = margins_in_points.left;
|
|
||||||
page_size_margins.margin_right = margins_in_points.right;
|
|
||||||
SetCustomMarginsToJobSettings(page_size_margins, job_settings);
|
|
||||||
}
|
|
||||||
job_settings->SetInteger(kSettingPreviewPageCount, 1);
|
|
||||||
|
|
||||||
// range
|
|
||||||
|
|
||||||
if (!settings.ranges().empty()) {
|
|
||||||
auto page_range_array = std::make_unique<base::ListValue>();
|
|
||||||
job_settings->Set(kSettingPageRange, std::move(page_range_array));
|
|
||||||
for (size_t i = 0; i < settings.ranges().size(); ++i) {
|
|
||||||
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
|
|
||||||
dict->SetInteger(kSettingPageRangeFrom, settings.ranges()[i].from + 1);
|
|
||||||
dict->SetInteger(kSettingPageRangeTo, settings.ranges()[i].to + 1);
|
|
||||||
page_range_array->Append(std::move(dict));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
job_settings->SetBoolean(kSettingCollate, settings.collate());
|
|
||||||
job_settings->SetInteger(kSettingCopies, 1);
|
|
||||||
job_settings->SetInteger(kSettingColor, settings.color());
|
|
||||||
job_settings->SetInteger(kSettingDuplexMode, settings.duplex_mode());
|
|
||||||
job_settings->SetBoolean(kSettingLandscape, settings.landscape());
|
|
||||||
job_settings->SetString(kSettingDeviceName, settings.device_name());
|
|
||||||
job_settings->SetInteger(kSettingScaleFactor, 100);
|
|
||||||
job_settings->SetBoolean("rasterizePDF", false);
|
|
||||||
|
|
||||||
job_settings->SetInteger("dpi", settings.dpi());
|
|
||||||
job_settings->SetInteger("dpiHorizontal", 72);
|
|
||||||
job_settings->SetInteger("dpiVertical", 72);
|
|
||||||
|
|
||||||
job_settings->SetBoolean(kSettingPrintToPDF, false);
|
|
||||||
job_settings->SetBoolean(kSettingCloudPrintDialog, false);
|
|
||||||
job_settings->SetBoolean(kSettingPrintWithPrivet, false);
|
|
||||||
job_settings->SetBoolean(kSettingPrintWithExtension, false);
|
|
||||||
|
|
||||||
job_settings->SetBoolean(kSettingShowSystemDialog, false);
|
|
||||||
job_settings->SetInteger(kSettingPreviewPageCount, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
class PrintingContextDelegate : public PrintingContext::Delegate {
|
|
||||||
public:
|
|
||||||
PrintingContextDelegate(int render_process_id, int render_frame_id);
|
|
||||||
~PrintingContextDelegate() override;
|
|
||||||
|
|
||||||
gfx::NativeView GetParentView() override;
|
|
||||||
std::string GetAppLocale() override;
|
|
||||||
|
|
||||||
// Not exposed to PrintingContext::Delegate because of dependency issues.
|
|
||||||
content::WebContents* GetWebContents();
|
|
||||||
|
|
||||||
private:
|
|
||||||
const int render_process_id_;
|
|
||||||
const int render_frame_id_;
|
|
||||||
};
|
|
||||||
|
|
||||||
PrintingContextDelegate::PrintingContextDelegate(int render_process_id,
|
|
||||||
int render_frame_id)
|
|
||||||
: render_process_id_(render_process_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);
|
|
||||||
auto* rfh =
|
|
||||||
content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
|
|
||||||
return rfh ? content::WebContents::FromRenderFrameHost(rfh) : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string PrintingContextDelegate::GetAppLocale() {
|
|
||||||
return g_browser_process->GetApplicationLocale();
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotificationCallback(PrintJobWorkerOwner* print_job,
|
|
||||||
JobEventDetails::Type detail_type,
|
|
||||||
int job_id,
|
|
||||||
PrintedDocument* document) {
|
|
||||||
JobEventDetails* details = new JobEventDetails(detail_type, job_id, document);
|
|
||||||
content::NotificationService::current()->Notify(
|
|
||||||
chrome::NOTIFICATION_PRINT_JOB_EVENT,
|
|
||||||
// We know that is is a PrintJob object in this circumstance.
|
|
||||||
content::Source<PrintJob>(static_cast<PrintJob*>(print_job)),
|
|
||||||
content::Details<JobEventDetails>(details));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PostOnOwnerThread(const scoped_refptr<PrintJobWorkerOwner>& owner,
|
|
||||||
PrintingContext::PrintSettingsCallback callback,
|
|
||||||
PrintingContext::Result result) {
|
|
||||||
owner->PostTask(FROM_HERE,
|
|
||||||
base::BindOnce(&HoldRefCallback, owner,
|
|
||||||
base::BindOnce(std::move(callback), result)));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
void PageNotificationCallback(PrintJobWorkerOwner* print_job,
|
|
||||||
JobEventDetails::Type detail_type,
|
|
||||||
int job_id,
|
|
||||||
PrintedDocument* document,
|
|
||||||
PrintedPage* page) {
|
|
||||||
JobEventDetails* details =
|
|
||||||
new JobEventDetails(detail_type, job_id, document, page);
|
|
||||||
content::NotificationService::current()->Notify(
|
|
||||||
chrome::NOTIFICATION_PRINT_JOB_EVENT,
|
|
||||||
// We know that is is a PrintJob object in this circumstance.
|
|
||||||
content::Source<PrintJob>(static_cast<PrintJob*>(print_job)),
|
|
||||||
content::Details<JobEventDetails>(details));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
PrintJobWorker::PrintJobWorker(int render_process_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_->RunsTasksInCurrentSequence());
|
|
||||||
|
|
||||||
printing_context_delegate_ = std::make_unique<PrintingContextDelegate>(
|
|
||||||
render_process_id, render_frame_id);
|
|
||||||
printing_context_ = PrintingContext::Create(printing_context_delegate_.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintJobWorker::~PrintJobWorker() {
|
|
||||||
// The object is normally deleted in the UI thread, but when the user
|
|
||||||
// cancels printing or in the case of print preview, the worker is destroyed
|
|
||||||
// on the I/O thread.
|
|
||||||
DCHECK(owner_->RunsTasksInCurrentSequence());
|
|
||||||
Stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJobWorker::SetNewOwner(PrintJobWorkerOwner* new_owner) {
|
|
||||||
DCHECK(page_number_ == PageNumber::npos());
|
|
||||||
owner_ = new_owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
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_->RunsTasksInCurrentSequence());
|
|
||||||
DCHECK_EQ(page_number_, PageNumber::npos());
|
|
||||||
|
|
||||||
// Recursive task processing is needed for the dialog in case it needs to be
|
|
||||||
// destroyed by a task.
|
|
||||||
// TODO(thestig): This code is wrong. SetNestableTasksAllowed(true) is needed
|
|
||||||
// on the thread where the PrintDlgEx is called, and definitely both calls
|
|
||||||
// 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.
|
|
||||||
if (ask_user_for_settings) {
|
|
||||||
BrowserThread::PostTask(
|
|
||||||
BrowserThread::UI, FROM_HERE,
|
|
||||||
base::BindOnce(
|
|
||||||
&HoldRefCallback, WrapRefCounted(owner_),
|
|
||||||
base::BindOnce(&PrintJobWorker::GetSettingsWithUI,
|
|
||||||
base::Unretained(this), document_page_count,
|
|
||||||
has_selection, is_scripted)));
|
|
||||||
} else if (!device_name.empty()) {
|
|
||||||
BrowserThread::PostTask(
|
|
||||||
BrowserThread::UI, FROM_HERE,
|
|
||||||
base::BindOnce(&HoldRefCallback, WrapRefCounted(owner_),
|
|
||||||
base::BindOnce(&PrintJobWorker::InitWithDeviceName,
|
|
||||||
base::Unretained(this), device_name)));
|
|
||||||
} else {
|
|
||||||
BrowserThread::PostTask(
|
|
||||||
BrowserThread::UI, FROM_HERE,
|
|
||||||
base::BindOnce(&HoldRefCallback, WrapRefCounted(owner_),
|
|
||||||
base::BindOnce(&PrintJobWorker::UseDefaultSettings,
|
|
||||||
base::Unretained(this))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJobWorker::SetSettings(
|
|
||||||
std::unique_ptr<base::DictionaryValue> new_settings) {
|
|
||||||
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
|
||||||
|
|
||||||
BrowserThread::PostTask(
|
|
||||||
BrowserThread::UI, FROM_HERE,
|
|
||||||
base::BindOnce(
|
|
||||||
&HoldRefCallback, WrapRefCounted(owner_),
|
|
||||||
base::BindOnce(&PrintJobWorker::UpdatePrintSettings,
|
|
||||||
base::Unretained(this), base::Passed(&new_settings))));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJobWorker::UpdatePrintSettings(
|
|
||||||
std::unique_ptr<base::DictionaryValue> new_settings) {
|
|
||||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
|
||||||
PrintingContext::Result result =
|
|
||||||
printing_context_->UpdatePrintSettings(*new_settings);
|
|
||||||
GetSettingsDone(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJobWorker::GetSettingsDone(PrintingContext::Result result) {
|
|
||||||
// Most PrintingContext functions may start a message loop and process
|
|
||||||
// message recursively, so disable recursive task processing.
|
|
||||||
// TODO(thestig): See above comment. SetNestableTasksAllowed(false) needs to
|
|
||||||
// be called on the same thread as the previous call. See
|
|
||||||
// http://crbug.com/73466
|
|
||||||
// MessageLoop::current()->SetNestableTasksAllowed(false);
|
|
||||||
|
|
||||||
// We can't use OnFailure() here since owner_ may not support notifications.
|
|
||||||
|
|
||||||
// PrintJob will create the new PrintedDocument.
|
|
||||||
owner_->PostTask(
|
|
||||||
FROM_HERE,
|
|
||||||
base::Bind(&PrintJobWorkerOwner::GetSettingsDone, WrapRefCounted(owner_),
|
|
||||||
printing_context_->settings(), result));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJobWorker::GetSettingsWithUI(int document_page_count,
|
|
||||||
bool has_selection,
|
|
||||||
bool is_scripted) {
|
|
||||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
|
||||||
|
|
||||||
// weak_factory_ creates pointers valid only on owner_ thread.
|
|
||||||
printing_context_->AskUserForSettings(
|
|
||||||
document_page_count, has_selection, is_scripted,
|
|
||||||
base::BindOnce(&PostOnOwnerThread, WrapRefCounted(owner_),
|
|
||||||
base::BindOnce(&PrintJobWorker::GetSettingsDone,
|
|
||||||
weak_factory_.GetWeakPtr())));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJobWorker::UseDefaultSettings() {
|
|
||||||
PrintingContext::Result result = printing_context_->UseDefaultSettings();
|
|
||||||
GetSettingsDone(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJobWorker::InitWithDeviceName(const base::string16& device_name) {
|
|
||||||
const auto& settings = printing_context_->settings();
|
|
||||||
std::unique_ptr<base::DictionaryValue> dic(new base::DictionaryValue);
|
|
||||||
PrintSettingsToJobSettings(settings, dic.get());
|
|
||||||
dic->SetString(kSettingDeviceName, device_name);
|
|
||||||
UpdatePrintSettings(std::move(dic));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJobWorker::StartPrinting(PrintedDocument* new_document) {
|
|
||||||
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
|
||||||
DCHECK_EQ(page_number_, PageNumber::npos());
|
|
||||||
DCHECK_EQ(document_.get(), new_document);
|
|
||||||
DCHECK(document_.get());
|
|
||||||
|
|
||||||
if (!document_.get() || page_number_ != PageNumber::npos() ||
|
|
||||||
document_.get() != new_document) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
base::string16 document_name =
|
|
||||||
printing::SimplifyDocumentTitle(document_->name());
|
|
||||||
PrintingContext::Result result =
|
|
||||||
printing_context_->NewDocument(document_name);
|
|
||||||
if (result != PrintingContext::OK) {
|
|
||||||
OnFailure();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to print already cached data. It may already have been generated for
|
|
||||||
// the print preview.
|
|
||||||
OnNewPage();
|
|
||||||
// Don't touch this anymore since the instance could be destroyed. It happens
|
|
||||||
// if all the pages are printed a one sweep and the client doesn't have a
|
|
||||||
// handle to us anymore. There's a timing issue involved between the worker
|
|
||||||
// thread and the UI thread. Take no chance.
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJobWorker::OnDocumentChanged(PrintedDocument* new_document) {
|
|
||||||
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
|
||||||
DCHECK_EQ(page_number_, PageNumber::npos());
|
|
||||||
|
|
||||||
if (page_number_ != PageNumber::npos())
|
|
||||||
return;
|
|
||||||
|
|
||||||
document_ = new_document;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJobWorker::PostWaitForPage() {
|
|
||||||
// We need to wait for the page to be available.
|
|
||||||
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
|
|
||||||
FROM_HERE,
|
|
||||||
base::BindOnce(&PrintJobWorker::OnNewPage, weak_factory_.GetWeakPtr()),
|
|
||||||
base::TimeDelta::FromMilliseconds(500));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
void PrintJobWorker::OnNewPage() {
|
|
||||||
if (!document_.get()) // Spurious message.
|
|
||||||
return;
|
|
||||||
|
|
||||||
// message_loop() could return NULL when the print job is cancelled.
|
|
||||||
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
|
||||||
|
|
||||||
if (page_number_ == PageNumber::npos()) {
|
|
||||||
// Find first page to print.
|
|
||||||
int page_count = document_->page_count();
|
|
||||||
if (!page_count) {
|
|
||||||
// We still don't know how many pages the document contains. We can't
|
|
||||||
// start to print the document yet since the header/footer may refer to
|
|
||||||
// the document's page count.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// We have enough information to initialize page_number_.
|
|
||||||
page_number_.Init(document_->settings(), page_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
DCHECK_NE(page_number_, PageNumber::npos());
|
|
||||||
while (true) {
|
|
||||||
// Is the page available?
|
|
||||||
scoped_refptr<PrintedPage> page = document_->GetPage(page_number_.ToInt());
|
|
||||||
if (!page.get()) {
|
|
||||||
PostWaitForPage();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// The page is there, print it.
|
|
||||||
SpoolPage(page.get());
|
|
||||||
++page_number_;
|
|
||||||
if (page_number_ == PageNumber::npos()) {
|
|
||||||
OnDocumentDone();
|
|
||||||
// Don't touch this anymore since the instance could be destroyed.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
void PrintJobWorker::OnNewPage() {
|
|
||||||
if (!document_.get()) // Spurious message.
|
|
||||||
return;
|
|
||||||
|
|
||||||
// message_loop() could return NULL when the print job is cancelled.
|
|
||||||
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
|
||||||
|
|
||||||
const MetafilePlayer* metafile = document_->GetMetafile();
|
|
||||||
if (!metafile) {
|
|
||||||
PostWaitForPage();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SpoolJob();
|
|
||||||
// Don't touch this anymore since the instance could be destroyed.
|
|
||||||
OnDocumentDone();
|
|
||||||
}
|
|
||||||
#endif // defined(OS_WIN)
|
|
||||||
|
|
||||||
void PrintJobWorker::Cancel() {
|
|
||||||
// This is the only function that can be called from any thread.
|
|
||||||
printing_context_->Cancel();
|
|
||||||
// Cannot touch any member variable since we don't know in which thread
|
|
||||||
// context we run.
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PrintJobWorker::IsRunning() const {
|
|
||||||
return thread_.IsRunning();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PrintJobWorker::PostTask(const base::Location& from_here,
|
|
||||||
const base::Closure& task) {
|
|
||||||
if (task_runner_.get())
|
|
||||||
return task_runner_->PostTask(from_here, task);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJobWorker::StopSoon() {
|
|
||||||
thread_.StopSoon();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJobWorker::Stop() {
|
|
||||||
thread_.Stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PrintJobWorker::Start() {
|
|
||||||
bool result = thread_.Start();
|
|
||||||
task_runner_ = thread_.task_runner();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintJobWorker::OnDocumentDone() {
|
|
||||||
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
|
||||||
DCHECK_EQ(page_number_, PageNumber::npos());
|
|
||||||
DCHECK(document_.get());
|
|
||||||
|
|
||||||
int job_id = printing_context_->job_id();
|
|
||||||
if (printing_context_->DocumentDone() != PrintingContext::OK) {
|
|
||||||
OnFailure();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
owner_->PostTask(FROM_HERE,
|
|
||||||
base::Bind(&NotificationCallback, base::RetainedRef(owner_),
|
|
||||||
JobEventDetails::DOC_DONE, job_id,
|
|
||||||
base::RetainedRef(document_)));
|
|
||||||
|
|
||||||
// Makes sure the variables are reinitialized.
|
|
||||||
document_ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
void PrintJobWorker::SpoolPage(PrintedPage* page) {
|
|
||||||
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
|
||||||
DCHECK_NE(page_number_, PageNumber::npos());
|
|
||||||
|
|
||||||
// Preprocess.
|
|
||||||
if (printing_context_->NewPage() != PrintingContext::OK) {
|
|
||||||
OnFailure();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actual printing.
|
|
||||||
document_->RenderPrintedPage(*page, printing_context_->context());
|
|
||||||
|
|
||||||
// Postprocess.
|
|
||||||
if (printing_context_->PageDone() != PrintingContext::OK) {
|
|
||||||
OnFailure();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Signal everyone that the page is printed.
|
|
||||||
owner_->PostTask(FROM_HERE,
|
|
||||||
base::BindRepeating(
|
|
||||||
&PageNotificationCallback, base::RetainedRef(owner_),
|
|
||||||
JobEventDetails::PAGE_DONE, printing_context_->job_id(),
|
|
||||||
base::RetainedRef(document_), base::RetainedRef(page)));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
void PrintJobWorker::SpoolJob() {
|
|
||||||
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
|
||||||
if (!document_->RenderPrintedDocument(printing_context_.get()))
|
|
||||||
OnFailure();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void PrintJobWorker::OnFailure() {
|
|
||||||
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
|
||||||
|
|
||||||
// We may loose our last reference by broadcasting the FAILED event.
|
|
||||||
scoped_refptr<PrintJobWorkerOwner> handle(owner_);
|
|
||||||
|
|
||||||
owner_->PostTask(
|
|
||||||
FROM_HERE, base::BindRepeating(
|
|
||||||
&NotificationCallback, base::RetainedRef(owner_),
|
|
||||||
JobEventDetails::FAILED, 0, base::RetainedRef(document_)));
|
|
||||||
Cancel();
|
|
||||||
|
|
||||||
// Makes sure the variables are reinitialized.
|
|
||||||
document_ = NULL;
|
|
||||||
page_number_ = PageNumber::npos();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace printing
|
|
|
@ -1,174 +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 CHROME_BROWSER_PRINTING_PRINT_JOB_WORKER_H_
|
|
||||||
#define CHROME_BROWSER_PRINTING_PRINT_JOB_WORKER_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "base/location.h"
|
|
||||||
#include "base/macros.h"
|
|
||||||
#include "base/memory/ref_counted.h"
|
|
||||||
#include "base/memory/weak_ptr.h"
|
|
||||||
#include "base/threading/thread.h"
|
|
||||||
#include "build/build_config.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"
|
|
||||||
#include "printing/printing_context.h"
|
|
||||||
|
|
||||||
namespace base {
|
|
||||||
class DictionaryValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
class PrintJob;
|
|
||||||
class PrintJobWorkerOwner;
|
|
||||||
class PrintedDocument;
|
|
||||||
class PrintedPage;
|
|
||||||
|
|
||||||
// Worker thread code. It manages the PrintingContext, which can be blocking
|
|
||||||
// and/or run a message loop. This is the object that generates most
|
|
||||||
// NOTIFY_PRINT_JOB_EVENT notifications, but they are generated through a
|
|
||||||
// NotificationTask task to be executed from the right thread, the UI thread.
|
|
||||||
// PrintJob always outlives its worker instance.
|
|
||||||
class PrintJobWorker {
|
|
||||||
public:
|
|
||||||
PrintJobWorker(int render_process_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 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);
|
|
||||||
|
|
||||||
// Starts the printing loop. Every pages are printed as soon as the data is
|
|
||||||
// available. Makes sure the new_document is the right one.
|
|
||||||
void StartPrinting(PrintedDocument* new_document);
|
|
||||||
|
|
||||||
// Updates the printed document.
|
|
||||||
void OnDocumentChanged(PrintedDocument* new_document);
|
|
||||||
|
|
||||||
// Dequeues waiting pages. Called when PrintJob receives a
|
|
||||||
// NOTIFY_PRINTED_DOCUMENT_UPDATED notification. It's time to look again if
|
|
||||||
// the next page can be printed.
|
|
||||||
void OnNewPage();
|
|
||||||
|
|
||||||
// This is the only function that can be called in a thread.
|
|
||||||
void Cancel();
|
|
||||||
|
|
||||||
// Returns true if the thread has been started, and not yet stopped.
|
|
||||||
bool IsRunning() const;
|
|
||||||
|
|
||||||
// Posts the given task to be run.
|
|
||||||
bool PostTask(const base::Location& from_here, const base::Closure& task);
|
|
||||||
|
|
||||||
// Signals the thread to exit in the near future.
|
|
||||||
void StopSoon();
|
|
||||||
|
|
||||||
// Signals the thread to exit and returns once the thread has exited.
|
|
||||||
void Stop();
|
|
||||||
|
|
||||||
// Starts the thread.
|
|
||||||
bool Start();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Retrieves the context for testing only.
|
|
||||||
PrintingContext* printing_context() { return printing_context_.get(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// The shared NotificationService service can only be accessed from the UI
|
|
||||||
// thread, so this class encloses the necessary information to send the
|
|
||||||
// notification from the right thread. Most NOTIFY_PRINT_JOB_EVENT
|
|
||||||
// notifications are sent this way, except USER_INIT_DONE, USER_INIT_CANCELED
|
|
||||||
// and DEFAULT_INIT_DONE. These three are sent through PrintJob::InitDone().
|
|
||||||
class NotificationTask;
|
|
||||||
|
|
||||||
// Posts a task to call OnNewPage(). Used to wait for pages/document to be
|
|
||||||
// available.
|
|
||||||
void PostWaitForPage();
|
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
// Renders a page in the printer.
|
|
||||||
void SpoolPage(PrintedPage* page);
|
|
||||||
#else
|
|
||||||
// Renders the document to the printer.
|
|
||||||
void SpoolJob();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Closes the job since spooling is done.
|
|
||||||
void OnDocumentDone();
|
|
||||||
|
|
||||||
// Discards the current document, the current page and cancels the printing
|
|
||||||
// context.
|
|
||||||
void OnFailure();
|
|
||||||
|
|
||||||
// Asks the user for print settings. Must be called on the UI thread.
|
|
||||||
// Required on Mac and Linux. Windows can display UI from non-main threads,
|
|
||||||
// but sticks with this for consistency.
|
|
||||||
void GetSettingsWithUI(int document_page_count,
|
|
||||||
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);
|
|
||||||
|
|
||||||
// Reports settings back to owner_.
|
|
||||||
void GetSettingsDone(PrintingContext::Result result);
|
|
||||||
|
|
||||||
// Use the default settings. When using GTK+ or Mac, this can still end up
|
|
||||||
// displaying a dialog. So this needs to happen from the UI thread on these
|
|
||||||
// systems.
|
|
||||||
void UseDefaultSettings();
|
|
||||||
|
|
||||||
// set the printer name
|
|
||||||
void InitWithDeviceName(const base::string16& device_name);
|
|
||||||
|
|
||||||
// Printing context delegate.
|
|
||||||
std::unique_ptr<PrintingContext::Delegate> printing_context_delegate_;
|
|
||||||
|
|
||||||
// Information about the printer setting.
|
|
||||||
std::unique_ptr<PrintingContext> printing_context_;
|
|
||||||
|
|
||||||
// The printed document. Only has read-only access.
|
|
||||||
scoped_refptr<PrintedDocument> document_;
|
|
||||||
|
|
||||||
// The print job owning this worker thread. It is guaranteed to outlive this
|
|
||||||
// object.
|
|
||||||
PrintJobWorkerOwner* owner_;
|
|
||||||
|
|
||||||
// Current page number to print.
|
|
||||||
PageNumber page_number_;
|
|
||||||
|
|
||||||
// Thread to run worker tasks.
|
|
||||||
base::Thread thread_;
|
|
||||||
|
|
||||||
// Tread-safe pointer to task runner of the |thread_|.
|
|
||||||
scoped_refptr<base::SequencedTaskRunner> task_runner_;
|
|
||||||
|
|
||||||
// Used to generate a WeakPtr for callbacks.
|
|
||||||
base::WeakPtrFactory<PrintJobWorker> weak_factory_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(PrintJobWorker);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace printing
|
|
||||||
|
|
||||||
#endif // CHROME_BROWSER_PRINTING_PRINT_JOB_WORKER_H_
|
|
|
@ -1,27 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#include "chrome/browser/printing/print_job_worker_owner.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::ThreadTaskRunnerHandle::Get()) {}
|
|
||||||
|
|
||||||
PrintJobWorkerOwner::~PrintJobWorkerOwner() {}
|
|
||||||
|
|
||||||
bool PrintJobWorkerOwner::RunsTasksInCurrentSequence() const {
|
|
||||||
return task_runner_->RunsTasksInCurrentSequence();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PrintJobWorkerOwner::PostTask(const base::Location& from_here,
|
|
||||||
base::OnceClosure task) {
|
|
||||||
return task_runner_->PostTask(from_here, std::move(task));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace printing
|
|
|
@ -1,65 +0,0 @@
|
||||||
// Copyright (c) 2011 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_PRINTING_PRINT_JOB_WORKER_OWNER_H__
|
|
||||||
#define CHROME_BROWSER_PRINTING_PRINT_JOB_WORKER_OWNER_H__
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "base/location.h"
|
|
||||||
#include "base/memory/ref_counted.h"
|
|
||||||
#include "printing/printing_context.h"
|
|
||||||
|
|
||||||
namespace base {
|
|
||||||
class MessageLoop;
|
|
||||||
class SequencedTaskRunner;
|
|
||||||
} // namespace base
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
class PrintJobWorker;
|
|
||||||
class PrintSettings;
|
|
||||||
|
|
||||||
class PrintJobWorkerOwner
|
|
||||||
: public base::RefCountedThreadSafe<PrintJobWorkerOwner> {
|
|
||||||
public:
|
|
||||||
PrintJobWorkerOwner();
|
|
||||||
|
|
||||||
// Finishes the initialization began by PrintJobWorker::GetSettings().
|
|
||||||
// Creates a new PrintedDocument if necessary. Solely meant to be called by
|
|
||||||
// PrintJobWorker.
|
|
||||||
virtual void GetSettingsDone(const PrintSettings& new_settings,
|
|
||||||
PrintingContext::Result result) = 0;
|
|
||||||
|
|
||||||
// Detach the PrintJobWorker associated to this object.
|
|
||||||
virtual std::unique_ptr<PrintJobWorker> DetachWorker(
|
|
||||||
PrintJobWorkerOwner* new_owner) = 0;
|
|
||||||
|
|
||||||
// Access the current settings.
|
|
||||||
virtual const PrintSettings& settings() const = 0;
|
|
||||||
|
|
||||||
// Cookie uniquely identifying the PrintedDocument and/or loaded settings.
|
|
||||||
virtual int cookie() const = 0;
|
|
||||||
|
|
||||||
// Returns true if the current thread is a thread on which a task
|
|
||||||
// may be run, and false if no task will be run on the current
|
|
||||||
// thread.
|
|
||||||
bool RunsTasksInCurrentSequence() const;
|
|
||||||
|
|
||||||
// Posts the given task to be run.
|
|
||||||
bool PostTask(const base::Location& from_here, base::OnceClosure task);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
friend class base::RefCountedThreadSafe<PrintJobWorkerOwner>;
|
|
||||||
|
|
||||||
virtual ~PrintJobWorkerOwner();
|
|
||||||
|
|
||||||
// Task runner reference. Used to send notifications in the right
|
|
||||||
// thread.
|
|
||||||
scoped_refptr<base::SequencedTaskRunner> task_runner_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace printing
|
|
||||||
|
|
||||||
#endif // CHROME_BROWSER_PRINTING_PRINT_JOB_WORKER_OWNER_H__
|
|
|
@ -1,142 +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 "chrome/browser/printing/print_preview_message_handler.h"
|
|
||||||
|
|
||||||
#include "base/bind.h"
|
|
||||||
#include "base/memory/shared_memory.h"
|
|
||||||
#include "chrome/browser/browser_process.h"
|
|
||||||
#include "chrome/browser/printing/print_job_manager.h"
|
|
||||||
#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"
|
|
||||||
#include "printing/pdf_metafile_skia.h"
|
|
||||||
#include "printing/print_job_constants.h"
|
|
||||||
|
|
||||||
#include "atom/common/node_includes.h"
|
|
||||||
|
|
||||||
using content::BrowserThread;
|
|
||||||
using content::WebContents;
|
|
||||||
|
|
||||||
DEFINE_WEB_CONTENTS_USER_DATA_KEY(printing::PrintPreviewMessageHandler);
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
void StopWorker(int document_cookie) {
|
|
||||||
if (document_cookie <= 0)
|
|
||||||
return;
|
|
||||||
scoped_refptr<printing::PrintQueriesQueue> queue =
|
|
||||||
g_browser_process->print_job_manager()->queue();
|
|
||||||
scoped_refptr<printing::PrinterQuery> printer_query =
|
|
||||||
queue->PopPrinterQuery(document_cookie);
|
|
||||||
if (printer_query.get()) {
|
|
||||||
BrowserThread::PostTask(
|
|
||||||
BrowserThread::IO, FROM_HERE,
|
|
||||||
base::Bind(&printing::PrinterQuery::StopWorker, printer_query));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char* CopyPDFDataOnIOThread(
|
|
||||||
const PrintHostMsg_DidPreviewDocument_Params& params) {
|
|
||||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
|
||||||
std::unique_ptr<base::SharedMemory> shared_buf(
|
|
||||||
new base::SharedMemory(params.metafile_data_handle, true));
|
|
||||||
if (!shared_buf->Map(params.data_size))
|
|
||||||
return nullptr;
|
|
||||||
char* pdf_data = new char[params.data_size];
|
|
||||||
memcpy(pdf_data, shared_buf->memory(), params.data_size);
|
|
||||||
return pdf_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FreeNodeBufferData(char* data, void* hint) {
|
|
||||||
delete[] data;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
PrintPreviewMessageHandler::PrintPreviewMessageHandler(
|
|
||||||
WebContents* web_contents)
|
|
||||||
: content::WebContentsObserver(web_contents) {
|
|
||||||
DCHECK(web_contents);
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintPreviewMessageHandler::~PrintPreviewMessageHandler() {}
|
|
||||||
|
|
||||||
void PrintPreviewMessageHandler::OnMetafileReadyForPrinting(
|
|
||||||
const PrintHostMsg_DidPreviewDocument_Params& params) {
|
|
||||||
// Always try to stop the worker.
|
|
||||||
StopWorker(params.document_cookie);
|
|
||||||
|
|
||||||
if (params.expected_pages_count <= 0) {
|
|
||||||
NOTREACHED();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BrowserThread::PostTaskAndReplyWithResult(
|
|
||||||
BrowserThread::IO, FROM_HERE, base::Bind(&CopyPDFDataOnIOThread, params),
|
|
||||||
base::Bind(&PrintPreviewMessageHandler::RunPrintToPDFCallback,
|
|
||||||
base::Unretained(this), params.preview_request_id,
|
|
||||||
params.data_size));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintPreviewMessageHandler::OnPrintPreviewFailed(int document_cookie,
|
|
||||||
int request_id) {
|
|
||||||
StopWorker(document_cookie);
|
|
||||||
RunPrintToPDFCallback(request_id, 0, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PrintPreviewMessageHandler::OnMessageReceived(
|
|
||||||
const IPC::Message& message,
|
|
||||||
content::RenderFrameHost* render_frame_host) {
|
|
||||||
bool handled = true;
|
|
||||||
IPC_BEGIN_MESSAGE_MAP(PrintPreviewMessageHandler, message)
|
|
||||||
IPC_MESSAGE_HANDLER(PrintHostMsg_MetafileReadyForPrinting,
|
|
||||||
OnMetafileReadyForPrinting)
|
|
||||||
IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewFailed, OnPrintPreviewFailed)
|
|
||||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
|
||||||
IPC_END_MESSAGE_MAP()
|
|
||||||
return handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintPreviewMessageHandler::PrintToPDF(
|
|
||||||
const base::DictionaryValue& options,
|
|
||||||
const atom::api::WebContents::PrintToPDFCallback& callback) {
|
|
||||||
int request_id;
|
|
||||||
options.GetInteger(printing::kPreviewRequestID, &request_id);
|
|
||||||
print_to_pdf_callback_map_[request_id] = callback;
|
|
||||||
|
|
||||||
content::RenderFrameHost* rfh = web_contents()->GetMainFrame();
|
|
||||||
rfh->Send(new PrintMsg_PrintPreview(rfh->GetRoutingID(), options));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintPreviewMessageHandler::RunPrintToPDFCallback(int request_id,
|
|
||||||
uint32_t data_size,
|
|
||||||
char* data) {
|
|
||||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
|
||||||
|
|
||||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
|
||||||
v8::Locker locker(isolate);
|
|
||||||
v8::HandleScope handle_scope(isolate);
|
|
||||||
if (data) {
|
|
||||||
v8::Local<v8::Value> buffer =
|
|
||||||
node::Buffer::New(isolate, data, static_cast<size_t>(data_size),
|
|
||||||
&FreeNodeBufferData, nullptr)
|
|
||||||
.ToLocalChecked();
|
|
||||||
print_to_pdf_callback_map_[request_id].Run(v8::Null(isolate), buffer);
|
|
||||||
} else {
|
|
||||||
v8::Local<v8::String> error_message =
|
|
||||||
v8::String::NewFromUtf8(isolate, "Failed to generate PDF");
|
|
||||||
print_to_pdf_callback_map_[request_id].Run(
|
|
||||||
v8::Exception::Error(error_message), v8::Null(isolate));
|
|
||||||
}
|
|
||||||
print_to_pdf_callback_map_.erase(request_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace printing
|
|
|
@ -1,60 +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 CHROME_BROWSER_PRINTING_PRINT_PREVIEW_MESSAGE_HANDLER_H_
|
|
||||||
#define CHROME_BROWSER_PRINTING_PRINT_PREVIEW_MESSAGE_HANDLER_H_
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#include "atom/browser/api/atom_api_web_contents.h"
|
|
||||||
#include "base/compiler_specific.h"
|
|
||||||
#include "content/public/browser/web_contents_observer.h"
|
|
||||||
#include "content/public/browser/web_contents_user_data.h"
|
|
||||||
|
|
||||||
struct PrintHostMsg_DidPreviewDocument_Params;
|
|
||||||
|
|
||||||
namespace content {
|
|
||||||
class WebContents;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
struct PageSizeMargins;
|
|
||||||
|
|
||||||
// Manages the print preview handling for a WebContents.
|
|
||||||
class PrintPreviewMessageHandler
|
|
||||||
: public content::WebContentsObserver,
|
|
||||||
public content::WebContentsUserData<PrintPreviewMessageHandler> {
|
|
||||||
public:
|
|
||||||
~PrintPreviewMessageHandler() override;
|
|
||||||
|
|
||||||
// content::WebContentsObserver implementation.
|
|
||||||
bool OnMessageReceived(const IPC::Message& message,
|
|
||||||
content::RenderFrameHost* render_frame_host) override;
|
|
||||||
|
|
||||||
void PrintToPDF(const base::DictionaryValue& options,
|
|
||||||
const atom::api::WebContents::PrintToPDFCallback& callback);
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef std::map<int, atom::api::WebContents::PrintToPDFCallback>
|
|
||||||
PrintToPDFCallbackMap;
|
|
||||||
|
|
||||||
explicit PrintPreviewMessageHandler(content::WebContents* web_contents);
|
|
||||||
friend class content::WebContentsUserData<PrintPreviewMessageHandler>;
|
|
||||||
|
|
||||||
// Message handlers.
|
|
||||||
void OnMetafileReadyForPrinting(
|
|
||||||
const PrintHostMsg_DidPreviewDocument_Params& params);
|
|
||||||
void OnPrintPreviewFailed(int document_cookie, int request_id);
|
|
||||||
|
|
||||||
void RunPrintToPDFCallback(int request_id, uint32_t data_size, char* data);
|
|
||||||
|
|
||||||
PrintToPDFCallbackMap print_to_pdf_callback_map_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(PrintPreviewMessageHandler);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace printing
|
|
||||||
|
|
||||||
#endif // CHROME_BROWSER_PRINTING_PRINT_PREVIEW_MESSAGE_HANDLER_H_
|
|
|
@ -1,508 +0,0 @@
|
||||||
// Copyright 2013 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/printing/print_view_manager_base.h"
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "base/bind.h"
|
|
||||||
#include "base/memory/ref_counted_memory.h"
|
|
||||||
#include "base/message_loop/message_loop.h"
|
|
||||||
#include "base/run_loop.h"
|
|
||||||
#include "base/strings/utf_string_conversions.h"
|
|
||||||
#include "base/timer/timer.h"
|
|
||||||
#include "chrome/browser/browser_process.h"
|
|
||||||
#include "chrome/browser/chrome_notification_types.h"
|
|
||||||
#include "chrome/browser/printing/print_job.h"
|
|
||||||
#include "chrome/browser/printing/print_job_manager.h"
|
|
||||||
#include "chrome/browser/printing/printer_query.h"
|
|
||||||
#include "chrome/browser/profiles/profile.h"
|
|
||||||
#include "chrome/browser/ui/simple_message_box.h"
|
|
||||||
#include "chrome/common/pref_names.h"
|
|
||||||
#include "chrome/common/print_messages.h"
|
|
||||||
#include "components/prefs/pref_service.h"
|
|
||||||
#include "content/public/browser/browser_thread.h"
|
|
||||||
#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"
|
|
||||||
#include "printing/printed_document.h"
|
|
||||||
#include "ui/base/l10n/l10n_util.h"
|
|
||||||
|
|
||||||
#if defined(ENABLE_FULL_PRINTING)
|
|
||||||
#include "chrome/browser/printing/print_error_dialog.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using base::TimeDelta;
|
|
||||||
using content::BrowserThread;
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
namespace {} // namespace
|
|
||||||
|
|
||||||
PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents)
|
|
||||||
: content::WebContentsObserver(web_contents),
|
|
||||||
number_pages_(0),
|
|
||||||
printing_succeeded_(false),
|
|
||||||
inside_inner_message_loop_(false),
|
|
||||||
cookie_(0),
|
|
||||||
queue_(g_browser_process->print_job_manager()->queue()) {
|
|
||||||
DCHECK(queue_.get());
|
|
||||||
expecting_first_page_ = true;
|
|
||||||
printing_enabled_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintViewManagerBase::~PrintViewManagerBase() {
|
|
||||||
ReleasePrinterQuery();
|
|
||||||
DisconnectFromCurrentPrintJob();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(DISABLE_BASIC_PRINTING)
|
|
||||||
bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh,
|
|
||||||
bool silent,
|
|
||||||
bool print_background,
|
|
||||||
const base::string16& device_name) {
|
|
||||||
int32_t id = rfh->GetRoutingID();
|
|
||||||
return PrintNowInternal(rfh, std::make_unique<PrintMsg_PrintPages>(
|
|
||||||
id, silent, print_background, device_name));
|
|
||||||
}
|
|
||||||
#endif // !DISABLE_BASIC_PRINTING
|
|
||||||
|
|
||||||
void PrintViewManagerBase::NavigationStopped() {
|
|
||||||
// Cancel the current job, wait for the worker to finish.
|
|
||||||
TerminatePrintJob(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintViewManagerBase::RenderProcessGone(base::TerminationStatus status) {
|
|
||||||
ReleasePrinterQuery();
|
|
||||||
|
|
||||||
if (!print_job_.get())
|
|
||||||
return;
|
|
||||||
|
|
||||||
scoped_refptr<PrintedDocument> document(print_job_->document());
|
|
||||||
if (document.get()) {
|
|
||||||
// If IsComplete() returns false, the document isn't completely rendered.
|
|
||||||
// Since our renderer is gone, there's nothing to do, cancel it. Otherwise,
|
|
||||||
// the print job may finish without problem.
|
|
||||||
TerminatePrintJob(!document->IsComplete());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
base::string16 PrintViewManagerBase::RenderSourceName() {
|
|
||||||
base::string16 name(web_contents()->GetTitle());
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintViewManagerBase::OnDidGetPrintedPagesCount(int cookie,
|
|
||||||
int number_pages) {
|
|
||||||
DCHECK_GT(cookie, 0);
|
|
||||||
DCHECK_GT(number_pages, 0);
|
|
||||||
number_pages_ = number_pages;
|
|
||||||
OpportunisticallyCreatePrintJob(cookie);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintViewManagerBase::OnDidGetDocumentCookie(int cookie) {
|
|
||||||
cookie_ = cookie;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintViewManagerBase::OnDidPrintPage(
|
|
||||||
const PrintHostMsg_DidPrintPage_Params& params) {
|
|
||||||
// TODO(rbpotter): Remove this check once there are no more spurious
|
|
||||||
// DidPrintPage messages.
|
|
||||||
#if !defined(OS_WIN)
|
|
||||||
if (!expecting_first_page_)
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!OpportunisticallyCreatePrintJob(params.document_cookie))
|
|
||||||
return;
|
|
||||||
|
|
||||||
PrintedDocument* document = print_job_->document();
|
|
||||||
if (!document || params.document_cookie != document->cookie()) {
|
|
||||||
// Out of sync. It may happen since we are completely asynchronous. Old
|
|
||||||
// spurious messages can be received if one of the processes is overloaded.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool metafile_must_be_valid = expecting_first_page_;
|
|
||||||
expecting_first_page_ = false;
|
|
||||||
|
|
||||||
base::SharedMemory shared_buf(params.metafile_data_handle, true);
|
|
||||||
if (metafile_must_be_valid) {
|
|
||||||
if (!shared_buf.Map(params.data_size)) {
|
|
||||||
NOTREACHED() << "couldn't map";
|
|
||||||
web_contents()->Stop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto metafile = std::make_unique<PdfMetafileSkia>();
|
|
||||||
if (metafile_must_be_valid) {
|
|
||||||
if (!metafile->InitFromData(shared_buf.memory(), params.data_size)) {
|
|
||||||
NOTREACHED() << "Invalid metafile header";
|
|
||||||
web_contents()->Stop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(OS_WIN)
|
|
||||||
// Update the rendered document. It will send notifications to the listener.
|
|
||||||
document->SetDocument(std::move(metafile), params.page_size,
|
|
||||||
params.content_area);
|
|
||||||
|
|
||||||
ShouldQuitFromInnerMessageLoop();
|
|
||||||
#else
|
|
||||||
print_job_->AppendPrintedPage(params.page_number);
|
|
||||||
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, print_text_with_gdi);
|
|
||||||
}
|
|
||||||
#endif // !OS_WIN
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintViewManagerBase::OnPrintingFailed(int cookie) {
|
|
||||||
if (cookie != cookie_) {
|
|
||||||
NOTREACHED();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReleasePrinterQuery();
|
|
||||||
|
|
||||||
content::NotificationService::current()->Notify(
|
|
||||||
chrome::NOTIFICATION_PRINT_JOB_RELEASED,
|
|
||||||
content::Source<content::WebContents>(web_contents()),
|
|
||||||
content::NotificationService::NoDetails());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintViewManagerBase::OnShowInvalidPrinterSettingsError() {
|
|
||||||
LOG(ERROR) << "Invalid printer settings";
|
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
|
||||||
OnDidGetPrintedPagesCount)
|
|
||||||
IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetDocumentCookie,
|
|
||||||
OnDidGetDocumentCookie)
|
|
||||||
IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintPage, OnDidPrintPage)
|
|
||||||
IPC_MESSAGE_HANDLER(PrintHostMsg_PrintingFailed, OnPrintingFailed)
|
|
||||||
IPC_MESSAGE_HANDLER(PrintHostMsg_ShowInvalidPrinterSettingsError,
|
|
||||||
OnShowInvalidPrinterSettingsError);
|
|
||||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
|
||||||
IPC_END_MESSAGE_MAP()
|
|
||||||
return handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintViewManagerBase::Observe(
|
|
||||||
int type,
|
|
||||||
const content::NotificationSource& source,
|
|
||||||
const content::NotificationDetails& details) {
|
|
||||||
switch (type) {
|
|
||||||
case chrome::NOTIFICATION_PRINT_JOB_EVENT: {
|
|
||||||
OnNotifyPrintJobEvent(*content::Details<JobEventDetails>(details).ptr());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
NOTREACHED();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintViewManagerBase::OnNotifyPrintJobEvent(
|
|
||||||
const JobEventDetails& event_details) {
|
|
||||||
switch (event_details.type()) {
|
|
||||||
case JobEventDetails::FAILED: {
|
|
||||||
TerminatePrintJob(true);
|
|
||||||
|
|
||||||
content::NotificationService::current()->Notify(
|
|
||||||
chrome::NOTIFICATION_PRINT_JOB_RELEASED,
|
|
||||||
content::Source<content::WebContents>(web_contents()),
|
|
||||||
content::NotificationService::NoDetails());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case JobEventDetails::USER_INIT_DONE:
|
|
||||||
case JobEventDetails::DEFAULT_INIT_DONE:
|
|
||||||
case JobEventDetails::USER_INIT_CANCELED: {
|
|
||||||
NOTREACHED();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case JobEventDetails::ALL_PAGES_REQUESTED: {
|
|
||||||
ShouldQuitFromInnerMessageLoop();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case JobEventDetails::NEW_DOC:
|
|
||||||
case JobEventDetails::NEW_PAGE:
|
|
||||||
case JobEventDetails::PAGE_DONE:
|
|
||||||
case JobEventDetails::DOC_DONE: {
|
|
||||||
// Don't care about the actual printing process.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case JobEventDetails::JOB_DONE: {
|
|
||||||
// Printing is done, we don't need it anymore.
|
|
||||||
// print_job_->is_job_pending() may still be true, depending on the order
|
|
||||||
// of object registration.
|
|
||||||
printing_succeeded_ = true;
|
|
||||||
ReleasePrintJob();
|
|
||||||
|
|
||||||
content::NotificationService::current()->Notify(
|
|
||||||
chrome::NOTIFICATION_PRINT_JOB_RELEASED,
|
|
||||||
content::Source<content::WebContents>(web_contents()),
|
|
||||||
content::NotificationService::NoDetails());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
NOTREACHED();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PrintViewManagerBase::RenderAllMissingPagesNow() {
|
|
||||||
if (!print_job_.get() || !print_job_->is_job_pending())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// We can't print if there is no renderer.
|
|
||||||
if (!web_contents() || !web_contents()->GetRenderViewHost() ||
|
|
||||||
!web_contents()->GetRenderViewHost()->IsRenderViewLive()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is the document already complete?
|
|
||||||
if (print_job_->document() && print_job_->document()->IsComplete()) {
|
|
||||||
printing_succeeded_ = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// WebContents is either dying or a second consecutive request to print
|
|
||||||
// happened before the first had time to finish. We need to render all the
|
|
||||||
// pages in an hurry if a print_job_ is still pending. No need to wait for it
|
|
||||||
// to actually spool the pages, only to have the renderer generate them. Run
|
|
||||||
// a message loop until we get our signal that the print job is satisfied.
|
|
||||||
// PrintJob will send a ALL_PAGES_REQUESTED after having received all the
|
|
||||||
// pages it needs. MessageLoop::current()->Quit() will be called as soon as
|
|
||||||
// print_job_->document()->IsComplete() is true on either ALL_PAGES_REQUESTED
|
|
||||||
// or in DidPrintPage(). The check is done in
|
|
||||||
// ShouldQuitFromInnerMessageLoop().
|
|
||||||
// BLOCKS until all the pages are received. (Need to enable recursive task)
|
|
||||||
if (!RunInnerMessageLoop()) {
|
|
||||||
// This function is always called from DisconnectFromCurrentPrintJob() so we
|
|
||||||
// know that the job will be stopped/canceled in any case.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintViewManagerBase::ShouldQuitFromInnerMessageLoop() {
|
|
||||||
// Look at the reason.
|
|
||||||
DCHECK(print_job_->document());
|
|
||||||
if (print_job_->document() && print_job_->document()->IsComplete() &&
|
|
||||||
inside_inner_message_loop_) {
|
|
||||||
// We are in a message loop created by RenderAllMissingPagesNow. Quit from
|
|
||||||
// it.
|
|
||||||
base::RunLoop::QuitCurrentWhenIdleDeprecated();
|
|
||||||
inside_inner_message_loop_ = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PrintViewManagerBase::CreateNewPrintJob(PrintJobWorkerOwner* job) {
|
|
||||||
DCHECK(!inside_inner_message_loop_);
|
|
||||||
|
|
||||||
// Disconnect the current print_job_.
|
|
||||||
DisconnectFromCurrentPrintJob();
|
|
||||||
|
|
||||||
// We can't print if there is no renderer.
|
|
||||||
if (!web_contents()->GetRenderViewHost() ||
|
|
||||||
!web_contents()->GetRenderViewHost()->IsRenderViewLive()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ask the renderer to generate the print preview, create the print preview
|
|
||||||
// view and switch to it, initialize the printer and show the print dialog.
|
|
||||||
DCHECK(!print_job_.get());
|
|
||||||
DCHECK(job);
|
|
||||||
if (!job)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
print_job_ = new PrintJob();
|
|
||||||
print_job_->Initialize(job, RenderSourceName(), number_pages_);
|
|
||||||
registrar_.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
|
|
||||||
content::Source<PrintJob>(print_job_.get()));
|
|
||||||
printing_succeeded_ = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintViewManagerBase::DisconnectFromCurrentPrintJob() {
|
|
||||||
// Make sure all the necessary rendered page are done. Don't bother with the
|
|
||||||
// return value.
|
|
||||||
bool result = RenderAllMissingPagesNow();
|
|
||||||
|
|
||||||
// Verify that assertion.
|
|
||||||
if (print_job_.get() && print_job_->document() &&
|
|
||||||
!print_job_->document()->IsComplete()) {
|
|
||||||
DCHECK(!result);
|
|
||||||
// That failed.
|
|
||||||
TerminatePrintJob(true);
|
|
||||||
} else {
|
|
||||||
// DO NOT wait for the job to finish.
|
|
||||||
ReleasePrintJob();
|
|
||||||
}
|
|
||||||
expecting_first_page_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintViewManagerBase::PrintingDone(bool success) {
|
|
||||||
auto* host = web_contents()->GetRenderViewHost();
|
|
||||||
if (print_job_.get()) {
|
|
||||||
if (host)
|
|
||||||
host->Send(new PrintMsg_PrintingDone(host->GetRoutingID(), success));
|
|
||||||
}
|
|
||||||
if (!callback.is_null()) {
|
|
||||||
callback.Run(success && print_job_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintViewManagerBase::TerminatePrintJob(bool cancel) {
|
|
||||||
if (!print_job_.get())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (cancel) {
|
|
||||||
// We don't need the metafile data anymore because the printing is canceled.
|
|
||||||
print_job_->Cancel();
|
|
||||||
inside_inner_message_loop_ = false;
|
|
||||||
} else {
|
|
||||||
DCHECK(!inside_inner_message_loop_);
|
|
||||||
DCHECK(!print_job_->document() || print_job_->document()->IsComplete());
|
|
||||||
|
|
||||||
// WebContents is either dying or navigating elsewhere. We need to render
|
|
||||||
// all the pages in an hurry if a print job is still pending. This does the
|
|
||||||
// trick since it runs a blocking message loop:
|
|
||||||
print_job_->Stop();
|
|
||||||
}
|
|
||||||
ReleasePrintJob();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintViewManagerBase::ReleasePrintJob() {
|
|
||||||
if (!print_job_.get())
|
|
||||||
return;
|
|
||||||
|
|
||||||
PrintingDone(printing_succeeded_);
|
|
||||||
|
|
||||||
registrar_.Remove(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
|
|
||||||
content::Source<PrintJob>(print_job_.get()));
|
|
||||||
// Don't close the worker thread.
|
|
||||||
print_job_ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PrintViewManagerBase::RunInnerMessageLoop() {
|
|
||||||
// This value may actually be too low:
|
|
||||||
//
|
|
||||||
// - If we're looping because of printer settings initialization, the premise
|
|
||||||
// here is that some poor users have their print server away on a VPN over a
|
|
||||||
// slow connection. In this situation, the simple fact of opening the printer
|
|
||||||
// can be dead slow. On the other side, we don't want to die infinitely for a
|
|
||||||
// real network error. Give the printer 60 seconds to comply.
|
|
||||||
//
|
|
||||||
// - If we're looping because of renderer page generation, the renderer could
|
|
||||||
// be CPU bound, the page overly complex/large or the system just
|
|
||||||
// memory-bound.
|
|
||||||
static const int kPrinterSettingsTimeout = 60000;
|
|
||||||
base::OneShotTimer quit_timer;
|
|
||||||
base::RunLoop run_loop;
|
|
||||||
quit_timer.Start(FROM_HERE,
|
|
||||||
TimeDelta::FromMilliseconds(kPrinterSettingsTimeout),
|
|
||||||
run_loop.QuitWhenIdleClosure());
|
|
||||||
|
|
||||||
inside_inner_message_loop_ = true;
|
|
||||||
|
|
||||||
// Need to enable recursive task.
|
|
||||||
{
|
|
||||||
base::MessageLoop::ScopedNestableTaskAllower allow;
|
|
||||||
base::RunLoop().Run();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool success = true;
|
|
||||||
if (inside_inner_message_loop_) {
|
|
||||||
// Ok we timed out. That's sad.
|
|
||||||
inside_inner_message_loop_ = false;
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) {
|
|
||||||
if (print_job_.get())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (!cookie) {
|
|
||||||
// Out of sync. It may happens since we are completely asynchronous. Old
|
|
||||||
// spurious message can happen if one of the processes is overloaded.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The job was initiated by a script. Time to get the corresponding worker
|
|
||||||
// thread.
|
|
||||||
scoped_refptr<PrinterQuery> queued_query = queue_->PopPrinterQuery(cookie);
|
|
||||||
if (!queued_query.get()) {
|
|
||||||
NOTREACHED();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!CreateNewPrintJob(queued_query.get())) {
|
|
||||||
// Don't kill anything.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Settings are already loaded. Go ahead. This will set
|
|
||||||
// print_job_->is_job_pending() to true.
|
|
||||||
print_job_->StartPrinting();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 rfh->Send(message.release());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintViewManagerBase::ReleasePrinterQuery() {
|
|
||||||
if (!cookie_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int cookie = cookie_;
|
|
||||||
cookie_ = 0;
|
|
||||||
|
|
||||||
printing::PrintJobManager* print_job_manager =
|
|
||||||
g_browser_process->print_job_manager();
|
|
||||||
// May be NULL in tests.
|
|
||||||
if (!print_job_manager)
|
|
||||||
return;
|
|
||||||
|
|
||||||
scoped_refptr<printing::PrinterQuery> printer_query;
|
|
||||||
printer_query = queue_->PopPrinterQuery(cookie);
|
|
||||||
if (!printer_query.get())
|
|
||||||
return;
|
|
||||||
BrowserThread::PostTask(
|
|
||||||
BrowserThread::IO, FROM_HERE,
|
|
||||||
base::Bind(&PrinterQuery::StopWorker, printer_query.get()));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace printing
|
|
|
@ -1,171 +0,0 @@
|
||||||
// Copyright 2013 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_PRINTING_PRINT_VIEW_MANAGER_BASE_H_
|
|
||||||
#define CHROME_BROWSER_PRINTING_PRINT_VIEW_MANAGER_BASE_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "base/callback.h"
|
|
||||||
#include "base/memory/ref_counted.h"
|
|
||||||
#include "base/strings/string16.h"
|
|
||||||
#include "components/prefs/pref_member.h"
|
|
||||||
#include "content/public/browser/notification_observer.h"
|
|
||||||
#include "content/public/browser/notification_registrar.h"
|
|
||||||
#include "content/public/browser/web_contents_observer.h"
|
|
||||||
#include "content/public/browser/web_contents_user_data.h"
|
|
||||||
|
|
||||||
struct PrintHostMsg_DidPrintPage_Params;
|
|
||||||
|
|
||||||
namespace content {
|
|
||||||
class RenderViewHost;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
class JobEventDetails;
|
|
||||||
class MetafilePlayer;
|
|
||||||
class PrintJob;
|
|
||||||
class PrintJobWorkerOwner;
|
|
||||||
class PrintQueriesQueue;
|
|
||||||
|
|
||||||
// Base class for managing the print commands for a WebContents.
|
|
||||||
class PrintViewManagerBase : public content::NotificationObserver,
|
|
||||||
public content::WebContentsObserver {
|
|
||||||
public:
|
|
||||||
~PrintViewManagerBase() override;
|
|
||||||
|
|
||||||
#if !defined(DISABLE_BASIC_PRINTING)
|
|
||||||
// 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(content::RenderFrameHost* rfh,
|
|
||||||
bool silent,
|
|
||||||
bool print_background,
|
|
||||||
const base::string16& device_name);
|
|
||||||
#endif // !DISABLE_BASIC_PRINTING
|
|
||||||
|
|
||||||
// PrintedPagesSource implementation.
|
|
||||||
base::string16 RenderSourceName();
|
|
||||||
|
|
||||||
void SetCallback(const base::Callback<void(bool)>& cb) { callback = cb; };
|
|
||||||
|
|
||||||
protected:
|
|
||||||
explicit PrintViewManagerBase(content::WebContents* web_contents);
|
|
||||||
|
|
||||||
// Helper method for Print*Now().
|
|
||||||
bool PrintNowInternal(content::RenderFrameHost* rfh,
|
|
||||||
std::unique_ptr<IPC::Message> message);
|
|
||||||
|
|
||||||
// Terminates or cancels the print job if one was pending.
|
|
||||||
void RenderProcessGone(base::TerminationStatus status) override;
|
|
||||||
|
|
||||||
// content::WebContentsObserver implementation.
|
|
||||||
bool OnMessageReceived(const IPC::Message& message,
|
|
||||||
content::RenderFrameHost* render_frame_host) override;
|
|
||||||
|
|
||||||
// IPC Message handlers.
|
|
||||||
virtual void OnPrintingFailed(int cookie);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// content::NotificationObserver implementation.
|
|
||||||
void Observe(int type,
|
|
||||||
const content::NotificationSource& source,
|
|
||||||
const content::NotificationDetails& details) override;
|
|
||||||
|
|
||||||
// Cancels the print job.
|
|
||||||
void NavigationStopped() override;
|
|
||||||
|
|
||||||
// IPC Message handlers.
|
|
||||||
void OnDidGetPrintedPagesCount(int cookie, int number_pages);
|
|
||||||
void OnDidGetDocumentCookie(int cookie);
|
|
||||||
void OnDidPrintPage(const PrintHostMsg_DidPrintPage_Params& params);
|
|
||||||
void OnShowInvalidPrinterSettingsError();
|
|
||||||
|
|
||||||
// Processes a NOTIFY_PRINT_JOB_EVENT notification.
|
|
||||||
void OnNotifyPrintJobEvent(const JobEventDetails& event_details);
|
|
||||||
|
|
||||||
// Requests the RenderView to render all the missing pages for the print job.
|
|
||||||
// No-op if no print job is pending. Returns true if at least one page has
|
|
||||||
// been requested to the renderer.
|
|
||||||
bool RenderAllMissingPagesNow();
|
|
||||||
|
|
||||||
// Quits the current message loop if these conditions hold true: a document is
|
|
||||||
// loaded and is complete and waiting_for_pages_to_be_rendered_ is true. This
|
|
||||||
// function is called in DidPrintPage() or on ALL_PAGES_REQUESTED
|
|
||||||
// notification. The inner message loop is created was created by
|
|
||||||
// RenderAllMissingPagesNow().
|
|
||||||
void ShouldQuitFromInnerMessageLoop();
|
|
||||||
|
|
||||||
// Creates a new empty print job. It has no settings loaded. If there is
|
|
||||||
// currently a print job, safely disconnect from it. Returns false if it is
|
|
||||||
// impossible to safely disconnect from the current print job or it is
|
|
||||||
// impossible to create a new print job.
|
|
||||||
bool CreateNewPrintJob(PrintJobWorkerOwner* job);
|
|
||||||
|
|
||||||
// Makes sure the current print_job_ has all its data before continuing, and
|
|
||||||
// disconnect from it.
|
|
||||||
void DisconnectFromCurrentPrintJob();
|
|
||||||
|
|
||||||
// Notify that the printing is done.
|
|
||||||
void PrintingDone(bool success);
|
|
||||||
|
|
||||||
// Terminates the print job. No-op if no print job has been created. If
|
|
||||||
// |cancel| is true, cancel it instead of waiting for the job to finish. Will
|
|
||||||
// call ReleasePrintJob().
|
|
||||||
void TerminatePrintJob(bool cancel);
|
|
||||||
|
|
||||||
// Releases print_job_. Correctly deregisters from notifications. No-op if
|
|
||||||
// no print job has been created.
|
|
||||||
void ReleasePrintJob();
|
|
||||||
|
|
||||||
// Runs an inner message loop. It will set inside_inner_message_loop_ to true
|
|
||||||
// while the blocking inner message loop is running. This is useful in cases
|
|
||||||
// where the RenderView is about to be destroyed while a printing job isn't
|
|
||||||
// finished.
|
|
||||||
bool RunInnerMessageLoop();
|
|
||||||
|
|
||||||
// In the case of Scripted Printing, where the renderer is controlling the
|
|
||||||
// control flow, print_job_ is initialized whenever possible. No-op is
|
|
||||||
// print_job_ is initialized.
|
|
||||||
bool OpportunisticallyCreatePrintJob(int cookie);
|
|
||||||
|
|
||||||
// Release the PrinterQuery associated with our |cookie_|.
|
|
||||||
void ReleasePrinterQuery();
|
|
||||||
|
|
||||||
content::NotificationRegistrar registrar_;
|
|
||||||
|
|
||||||
// Manages the low-level talk to the printer.
|
|
||||||
scoped_refptr<PrintJob> print_job_;
|
|
||||||
|
|
||||||
// Number of pages to print in the print job.
|
|
||||||
int number_pages_;
|
|
||||||
|
|
||||||
// Indication of success of the print job.
|
|
||||||
bool printing_succeeded_;
|
|
||||||
|
|
||||||
// Running an inner message loop inside RenderAllMissingPagesNow(). This means
|
|
||||||
// we are _blocking_ until all the necessary pages have been rendered or the
|
|
||||||
// print settings are being loaded.
|
|
||||||
bool inside_inner_message_loop_;
|
|
||||||
|
|
||||||
// Set to true when OnDidPrintPage() should be expecting the first page.
|
|
||||||
bool expecting_first_page_;
|
|
||||||
|
|
||||||
// The document cookie of the current PrinterQuery.
|
|
||||||
int cookie_;
|
|
||||||
|
|
||||||
// Whether printing is enabled.
|
|
||||||
bool printing_enabled_;
|
|
||||||
|
|
||||||
scoped_refptr<printing::PrintQueriesQueue> queue_;
|
|
||||||
|
|
||||||
base::Callback<void(bool)> callback;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(PrintViewManagerBase);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace printing
|
|
||||||
|
|
||||||
#endif // CHROME_BROWSER_PRINTING_PRINT_VIEW_MANAGER_BASE_H_
|
|
|
@ -1,46 +0,0 @@
|
||||||
// Copyright 2013 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/printing/print_view_manager_basic.h"
|
|
||||||
|
|
||||||
#if defined(OS_ANDROID)
|
|
||||||
#include "base/file_descriptor_posix.h"
|
|
||||||
#include "chrome/common/print_messages.h"
|
|
||||||
#include "printing/printing_context_android.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DEFINE_WEB_CONTENTS_USER_DATA_KEY(printing::PrintViewManagerBasic);
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
PrintViewManagerBasic::PrintViewManagerBasic(content::WebContents* web_contents)
|
|
||||||
: PrintViewManagerBase(web_contents) {}
|
|
||||||
|
|
||||||
PrintViewManagerBasic::~PrintViewManagerBasic() {}
|
|
||||||
|
|
||||||
#if defined(OS_ANDROID)
|
|
||||||
void PrintViewManagerBasic::RenderProcessGone(base::TerminationStatus status) {
|
|
||||||
PrintingContextAndroid::PdfWritingDone(file_descriptor_.fd, false);
|
|
||||||
file_descriptor_ = base::FileDescriptor(-1, false);
|
|
||||||
PrintViewManagerBase::RenderProcessGone(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintViewManagerBasic::OnPrintingFailed(int cookie) {
|
|
||||||
PrintingContextAndroid::PdfWritingDone(file_descriptor_.fd, false);
|
|
||||||
file_descriptor_ = base::FileDescriptor(-1, false);
|
|
||||||
PrintViewManagerBase::OnPrintingFailed(cookie);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PrintViewManagerBasic::OnMessageReceived(const IPC::Message& message) {
|
|
||||||
bool handled = true;
|
|
||||||
IPC_BEGIN_MESSAGE_MAP(PrintViewManagerBasic, message)
|
|
||||||
IPC_MESSAGE_HANDLER(PrintHostMsg_PrintingFailed, OnPrintingFailed)
|
|
||||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
|
||||||
IPC_END_MESSAGE_MAP()
|
|
||||||
|
|
||||||
return handled ? true : PrintViewManagerBase::OnMessageReceived(message);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace printing
|
|
|
@ -1,57 +0,0 @@
|
||||||
// Copyright 2013 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_PRINTING_PRINT_VIEW_MANAGER_BASIC_H_
|
|
||||||
#define CHROME_BROWSER_PRINTING_PRINT_VIEW_MANAGER_BASIC_H_
|
|
||||||
|
|
||||||
#include "chrome/browser/printing/print_view_manager_base.h"
|
|
||||||
#include "content/public/browser/web_contents_user_data.h"
|
|
||||||
|
|
||||||
#if defined(OS_ANDROID)
|
|
||||||
#include "base/file_descriptor_posix.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
// Manages the print commands for a WebContents - basic version.
|
|
||||||
class PrintViewManagerBasic
|
|
||||||
: public PrintViewManagerBase,
|
|
||||||
public content::WebContentsUserData<PrintViewManagerBasic> {
|
|
||||||
public:
|
|
||||||
~PrintViewManagerBasic() override;
|
|
||||||
|
|
||||||
#if defined(OS_ANDROID)
|
|
||||||
// Sets the file descriptor into which the PDF will be written.
|
|
||||||
void set_file_descriptor(const base::FileDescriptor& file_descriptor) {
|
|
||||||
file_descriptor_ = file_descriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gets the file descriptor into which the PDF will be written.
|
|
||||||
base::FileDescriptor file_descriptor() const { return file_descriptor_; }
|
|
||||||
|
|
||||||
// content::WebContentsObserver implementation.
|
|
||||||
// Terminates or cancels the print job if one was pending.
|
|
||||||
virtual void RenderProcessGone(base::TerminationStatus status) override;
|
|
||||||
|
|
||||||
// content::WebContentsObserver implementation.
|
|
||||||
virtual bool OnMessageReceived(const IPC::Message& message) override;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit PrintViewManagerBasic(content::WebContents* web_contents);
|
|
||||||
friend class content::WebContentsUserData<PrintViewManagerBasic>;
|
|
||||||
|
|
||||||
#if defined(OS_ANDROID)
|
|
||||||
virtual void OnPrintingFailed(int cookie) override;
|
|
||||||
|
|
||||||
// The file descriptor into which the PDF of the page will be written.
|
|
||||||
base::FileDescriptor file_descriptor_;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(PrintViewManagerBasic);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace printing
|
|
||||||
|
|
||||||
#endif // CHROME_BROWSER_PRINTING_PRINT_VIEW_MANAGER_BASIC_H_
|
|
|
@ -1,23 +0,0 @@
|
||||||
// Copyright (c) 2011 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_PRINTING_PRINT_VIEW_MANAGER_OBSERVER_H_
|
|
||||||
#define CHROME_BROWSER_PRINTING_PRINT_VIEW_MANAGER_OBSERVER_H_
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
// An interface the PrintViewManager uses to notify an observer when the print
|
|
||||||
// dialog is shown. Register the observer via PrintViewManager::set_observer.
|
|
||||||
class PrintViewManagerObserver {
|
|
||||||
public:
|
|
||||||
// Notifies the observer that the print dialog was shown.
|
|
||||||
virtual void OnPrintDialogShown() = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual ~PrintViewManagerObserver() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace printing
|
|
||||||
|
|
||||||
#endif // CHROME_BROWSER_PRINTING_PRINT_VIEW_MANAGER_OBSERVER_H_
|
|
|
@ -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.
|
|
||||||
|
|
||||||
#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"
|
|
||||||
#include "base/threading/thread_restrictions.h"
|
|
||||||
#include "base/values.h"
|
|
||||||
#include "chrome/browser/printing/print_job_worker.h"
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
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) {
|
|
||||||
DCHECK(base::MessageLoopForIO::IsCurrent());
|
|
||||||
}
|
|
||||||
|
|
||||||
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_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrinterQuery::GetSettingsDone(const PrintSettings& new_settings,
|
|
||||||
PrintingContext::Result result) {
|
|
||||||
is_print_dialog_box_shown_ = false;
|
|
||||||
last_status_ = result;
|
|
||||||
if (result != PrintingContext::FAILED) {
|
|
||||||
settings_ = new_settings;
|
|
||||||
cookie_ = PrintSettings::NewCookie();
|
|
||||||
} else {
|
|
||||||
// Failure.
|
|
||||||
cookie_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!callback_.is_null()) {
|
|
||||||
// This may cause reentrancy like to call StopWorker().
|
|
||||||
callback_.Run();
|
|
||||||
callback_.Reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<PrintJobWorker> PrinterQuery::DetachWorker(
|
|
||||||
PrintJobWorkerOwner* new_owner) {
|
|
||||||
DCHECK(callback_.is_null());
|
|
||||||
DCHECK(worker_);
|
|
||||||
|
|
||||||
worker_->SetNewOwner(new_owner);
|
|
||||||
return std::move(worker_);
|
|
||||||
}
|
|
||||||
|
|
||||||
const PrintSettings& PrinterQuery::settings() const {
|
|
||||||
return settings_;
|
|
||||||
}
|
|
||||||
|
|
||||||
int PrinterQuery::cookie() const {
|
|
||||||
return cookie_;
|
|
||||||
}
|
|
||||||
|
|
||||||
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(RunsTasksInCurrentSequence());
|
|
||||||
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 == 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(GetSettingsAskParam ask_user_for_settings,
|
|
||||||
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(RunsTasksInCurrentSequence());
|
|
||||||
DCHECK(!is_print_dialog_box_shown_);
|
|
||||||
StartWorker(callback);
|
|
||||||
|
|
||||||
is_print_dialog_box_shown_ = false;
|
|
||||||
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, device_name));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrinterQuery::SetSettings(
|
|
||||||
std::unique_ptr<base::DictionaryValue> new_settings,
|
|
||||||
const base::Closure& callback) {
|
|
||||||
StartWorker(callback);
|
|
||||||
|
|
||||||
worker_->PostTask(FROM_HERE, base::Bind(&PrintJobWorker::SetSettings,
|
|
||||||
base::Unretained(worker_.get()),
|
|
||||||
base::Passed(&new_settings)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrinterQuery::StartWorker(const base::Closure& callback) {
|
|
||||||
DCHECK(callback_.is_null());
|
|
||||||
DCHECK(worker_);
|
|
||||||
|
|
||||||
// Lazily create the worker thread. There is one worker thread per print job.
|
|
||||||
if (!worker_->IsRunning())
|
|
||||||
worker_->Start();
|
|
||||||
|
|
||||||
callback_ = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrinterQuery::StopWorker() {
|
|
||||||
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.
|
|
||||||
base::ThreadRestrictions::ScopedAllowIO allow_io;
|
|
||||||
worker_->Stop();
|
|
||||||
worker_.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PrinterQuery::is_callback_pending() const {
|
|
||||||
return !callback_.is_null();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PrinterQuery::is_valid() const {
|
|
||||||
return !!worker_;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace printing
|
|
|
@ -1,111 +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 CHROME_BROWSER_PRINTING_PRINTER_QUERY_H_
|
|
||||||
#define CHROME_BROWSER_PRINTING_PRINTER_QUERY_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#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"
|
|
||||||
|
|
||||||
namespace base {
|
|
||||||
class DictionaryValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
class PrintDestinationInterface;
|
|
||||||
class PrintJobWorker;
|
|
||||||
|
|
||||||
// Query the printer for settings.
|
|
||||||
class PrinterQuery : public PrintJobWorkerOwner {
|
|
||||||
public:
|
|
||||||
// GetSettings() UI parameter.
|
|
||||||
enum class GetSettingsAskParam {
|
|
||||||
DEFAULTS,
|
|
||||||
ASK_USER,
|
|
||||||
};
|
|
||||||
|
|
||||||
PrinterQuery(int render_process_id, int render_frame_id);
|
|
||||||
|
|
||||||
// PrintJobWorkerOwner implementation.
|
|
||||||
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,
|
|
||||||
bool is_scripted,
|
|
||||||
bool is_modifiable,
|
|
||||||
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::string16& device_name,
|
|
||||||
const base::Closure& callback);
|
|
||||||
|
|
||||||
// Updates the current settings with |new_settings| dictionary values.
|
|
||||||
void SetSettings(std::unique_ptr<base::DictionaryValue> new_settings,
|
|
||||||
const base::Closure& callback);
|
|
||||||
|
|
||||||
// Stops the worker thread since the client is done with this object.
|
|
||||||
void StopWorker();
|
|
||||||
|
|
||||||
// Returns true if a GetSettings() call is pending completion.
|
|
||||||
bool is_callback_pending() const;
|
|
||||||
|
|
||||||
PrintingContext::Result last_status() const { return last_status_; }
|
|
||||||
|
|
||||||
// Returns if a worker thread is still associated to this instance.
|
|
||||||
bool is_valid() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
~PrinterQuery() override;
|
|
||||||
|
|
||||||
// Lazy create the worker thread. There is one worker thread per print job.
|
|
||||||
void StartWorker(const base::Closure& callback);
|
|
||||||
|
|
||||||
// All the UI is done in a worker thread because many Win32 print functions
|
|
||||||
// are blocking and enters a message loop without your consent. There is one
|
|
||||||
// worker thread per print job.
|
|
||||||
std::unique_ptr<PrintJobWorker> worker_;
|
|
||||||
|
|
||||||
// Cache of the print context settings for access in the UI thread.
|
|
||||||
PrintSettings settings_;
|
|
||||||
|
|
||||||
// Is the Print... dialog box currently shown.
|
|
||||||
bool is_print_dialog_box_shown_;
|
|
||||||
|
|
||||||
// Cookie that make this instance unique.
|
|
||||||
int cookie_;
|
|
||||||
|
|
||||||
// Results from the last GetSettingsDone() callback.
|
|
||||||
PrintingContext::Result last_status_;
|
|
||||||
|
|
||||||
// Callback waiting to be run.
|
|
||||||
base::Closure callback_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(PrinterQuery);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace printing
|
|
||||||
|
|
||||||
#endif // CHROME_BROWSER_PRINTING_PRINTER_QUERY_H_
|
|
|
@ -1,328 +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 "chrome/browser/printing/printing_message_filter.h"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "base/bind.h"
|
|
||||||
#include "chrome/browser/browser_process.h"
|
|
||||||
#include "chrome/browser/printing/print_job_manager.h"
|
|
||||||
#include "chrome/browser/printing/printer_query.h"
|
|
||||||
#include "chrome/browser/profiles/profile.h"
|
|
||||||
#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_frame_host.h"
|
|
||||||
#include "content/public/browser/web_contents.h"
|
|
||||||
#include "content/public/common/child_process_host.h"
|
|
||||||
#include "printing/buildflags/buildflags.h"
|
|
||||||
|
|
||||||
#if defined(OS_ANDROID)
|
|
||||||
#include "base/strings/string_number_conversions.h"
|
|
||||||
#include "chrome/browser/printing/print_view_manager_basic.h"
|
|
||||||
#include "printing/printing_context_android.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using content::BrowserThread;
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
void RenderParamsFromPrintSettings(const PrintSettings& settings,
|
|
||||||
PrintMsg_Print_Params* params) {
|
|
||||||
params->page_size = settings.page_setup_device_units().physical_size();
|
|
||||||
params->content_size.SetSize(
|
|
||||||
settings.page_setup_device_units().content_area().width(),
|
|
||||||
settings.page_setup_device_units().content_area().height());
|
|
||||||
params->printable_area.SetRect(
|
|
||||||
settings.page_setup_device_units().printable_area().x(),
|
|
||||||
settings.page_setup_device_units().printable_area().y(),
|
|
||||||
settings.page_setup_device_units().printable_area().width(),
|
|
||||||
settings.page_setup_device_units().printable_area().height());
|
|
||||||
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();
|
|
||||||
// Always use an invalid cookie.
|
|
||||||
params->document_cookie = 0;
|
|
||||||
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)
|
|
||||||
: BrowserMessageFilter(PrintMsgStart),
|
|
||||||
render_process_id_(render_process_id),
|
|
||||||
queue_(g_browser_process->print_job_manager()->queue()) {
|
|
||||||
DCHECK(queue_.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintingMessageFilter::~PrintingMessageFilter() {}
|
|
||||||
|
|
||||||
void PrintingMessageFilter::OnDestruct() const {
|
|
||||||
BrowserThread::DeleteOnUIThread::Destruct(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintingMessageFilter::OverrideThreadForMessage(
|
|
||||||
const IPC::Message& message,
|
|
||||||
BrowserThread::ID* thread) {
|
|
||||||
#if defined(OS_ANDROID)
|
|
||||||
if (message.type() == PrintHostMsg_AllocateTempFileForPrinting::ID ||
|
|
||||||
message.type() == PrintHostMsg_TempFileForPrintingWritten::ID) {
|
|
||||||
*thread = BrowserThread::UI;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PrintingMessageFilter::OnMessageReceived(const IPC::Message& message) {
|
|
||||||
bool handled = true;
|
|
||||||
IPC_BEGIN_MESSAGE_MAP(PrintingMessageFilter, message)
|
|
||||||
#if defined(OS_ANDROID)
|
|
||||||
IPC_MESSAGE_HANDLER(PrintHostMsg_AllocateTempFileForPrinting,
|
|
||||||
OnAllocateTempFileForPrinting)
|
|
||||||
IPC_MESSAGE_HANDLER(PrintHostMsg_TempFileForPrintingWritten,
|
|
||||||
OnTempFileForPrintingWritten)
|
|
||||||
#endif
|
|
||||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_GetDefaultPrintSettings,
|
|
||||||
OnGetDefaultPrintSettings)
|
|
||||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_InitSettingWithDeviceName,
|
|
||||||
OnInitSettingWithDeviceName)
|
|
||||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_ScriptedPrint, OnScriptedPrint)
|
|
||||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_UpdatePrintSettings,
|
|
||||||
OnUpdatePrintSettings)
|
|
||||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
|
||||||
IPC_END_MESSAGE_MAP()
|
|
||||||
return handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(OS_ANDROID)
|
|
||||||
void PrintingMessageFilter::OnAllocateTempFileForPrinting(
|
|
||||||
int render_frame_id,
|
|
||||||
base::FileDescriptor* temp_file_fd,
|
|
||||||
int* sequence_number) {
|
|
||||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
|
||||||
PrintViewManagerBasic* print_view_manager =
|
|
||||||
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.
|
|
||||||
temp_file_fd->fd = print_view_manager->file_descriptor().fd;
|
|
||||||
temp_file_fd->auto_close = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintingMessageFilter::OnTempFileForPrintingWritten(int render_frame_id,
|
|
||||||
int sequence_number) {
|
|
||||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
|
||||||
PrintViewManagerBasic* print_view_manager =
|
|
||||||
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 (false) {
|
|
||||||
// Reply with NULL query.
|
|
||||||
OnGetDefaultPrintSettingsReply(printer_query, reply_msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
printer_query = queue_->PopPrinterQuery(0);
|
|
||||||
if (!printer_query.get()) {
|
|
||||||
printer_query =
|
|
||||||
queue_->CreatePrinterQuery(render_process_id_, reply_msg->routing_id());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loads default settings. This is asynchronous, only the IPC message sender
|
|
||||||
// will hang until the settings are retrieved.
|
|
||||||
printer_query->GetSettings(
|
|
||||||
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,
|
|
||||||
IPC::Message* reply_msg) {
|
|
||||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
|
||||||
scoped_refptr<PrinterQuery> printer_query;
|
|
||||||
printer_query = queue_->PopPrinterQuery(0);
|
|
||||||
if (!printer_query.get()) {
|
|
||||||
printer_query =
|
|
||||||
queue_->CreatePrinterQuery(render_process_id_, reply_msg->routing_id());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loads default settings. This is asynchronous, only the IPC message sender
|
|
||||||
// will hang until the settings are retrieved.
|
|
||||||
printer_query->GetSettings(
|
|
||||||
PrinterQuery::GetSettingsAskParam::DEFAULTS, 0, false, DEFAULT_MARGINS,
|
|
||||||
true, true, device_name,
|
|
||||||
base::Bind(&PrintingMessageFilter::OnGetDefaultPrintSettingsReply, this,
|
|
||||||
printer_query, reply_msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintingMessageFilter::OnGetDefaultPrintSettingsReply(
|
|
||||||
scoped_refptr<PrinterQuery> printer_query,
|
|
||||||
IPC::Message* reply_msg) {
|
|
||||||
PrintMsg_Print_Params params;
|
|
||||||
if (!printer_query.get() ||
|
|
||||||
printer_query->last_status() != PrintingContext::OK) {
|
|
||||||
params.Reset();
|
|
||||||
} else {
|
|
||||||
RenderParamsFromPrintSettings(printer_query->settings(), ¶ms);
|
|
||||||
params.document_cookie = printer_query->cookie();
|
|
||||||
}
|
|
||||||
PrintHostMsg_GetDefaultPrintSettings::WriteReplyParams(reply_msg, params);
|
|
||||||
Send(reply_msg);
|
|
||||||
// If printing was enabled.
|
|
||||||
if (printer_query.get()) {
|
|
||||||
// If user hasn't cancelled.
|
|
||||||
if (printer_query->cookie() && printer_query->settings().dpi()) {
|
|
||||||
queue_->QueuePrinterQuery(printer_query.get());
|
|
||||||
} else {
|
|
||||||
printer_query->StopWorker();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintingMessageFilter::OnScriptedPrint(
|
|
||||||
const PrintHostMsg_ScriptedPrint_Params& params,
|
|
||||||
IPC::Message* reply_msg) {
|
|
||||||
scoped_refptr<PrinterQuery> printer_query =
|
|
||||||
queue_->PopPrinterQuery(params.cookie);
|
|
||||||
if (!printer_query.get()) {
|
|
||||||
printer_query =
|
|
||||||
queue_->CreatePrinterQuery(render_process_id_, reply_msg->routing_id());
|
|
||||||
}
|
|
||||||
printer_query->GetSettings(
|
|
||||||
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(
|
|
||||||
scoped_refptr<PrinterQuery> printer_query,
|
|
||||||
IPC::Message* reply_msg) {
|
|
||||||
PrintMsg_PrintPages_Params params;
|
|
||||||
#if defined(OS_ANDROID)
|
|
||||||
// We need to save the routing ID here because Send method below deletes the
|
|
||||||
// |reply_msg| before we can get the routing ID for the Android code.
|
|
||||||
int routing_id = reply_msg->routing_id();
|
|
||||||
#endif
|
|
||||||
if (printer_query->last_status() != PrintingContext::OK ||
|
|
||||||
!printer_query->settings().dpi()) {
|
|
||||||
params.Reset();
|
|
||||||
} else {
|
|
||||||
RenderParamsFromPrintSettings(printer_query->settings(), ¶ms.params);
|
|
||||||
params.params.document_cookie = printer_query->cookie();
|
|
||||||
params.pages = PageRange::GetPages(printer_query->settings().ranges());
|
|
||||||
}
|
|
||||||
PrintHostMsg_ScriptedPrint::WriteReplyParams(reply_msg, params);
|
|
||||||
Send(reply_msg);
|
|
||||||
if (params.params.dpi && params.params.document_cookie) {
|
|
||||||
#if defined(OS_ANDROID)
|
|
||||||
int file_descriptor;
|
|
||||||
const base::string16& device_name = printer_query->settings().device_name();
|
|
||||||
if (base::StringToInt(device_name, &file_descriptor)) {
|
|
||||||
BrowserThread::PostTask(
|
|
||||||
BrowserThread::UI, FROM_HERE,
|
|
||||||
base::Bind(&PrintingMessageFilter::UpdateFileDescriptor, this,
|
|
||||||
routing_id, file_descriptor));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
queue_->QueuePrinterQuery(printer_query.get());
|
|
||||||
} else {
|
|
||||||
printer_query->StopWorker();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(OS_ANDROID)
|
|
||||||
void PrintingMessageFilter::UpdateFileDescriptor(int render_view_id, int fd) {
|
|
||||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
|
||||||
content::WebContents* wc = GetWebContentsForRenderView(render_view_id);
|
|
||||||
if (!wc)
|
|
||||||
return;
|
|
||||||
PrintViewManagerBasic* print_view_manager =
|
|
||||||
PrintViewManagerBasic::FromWebContents(wc);
|
|
||||||
print_view_manager->set_file_descriptor(base::FileDescriptor(fd, false));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void PrintingMessageFilter::OnUpdatePrintSettings(
|
|
||||||
int document_cookie,
|
|
||||||
const base::DictionaryValue& job_settings,
|
|
||||||
IPC::Message* reply_msg) {
|
|
||||||
std::unique_ptr<base::DictionaryValue> new_settings(job_settings.DeepCopy());
|
|
||||||
|
|
||||||
scoped_refptr<PrinterQuery> printer_query;
|
|
||||||
printer_query = queue_->PopPrinterQuery(document_cookie);
|
|
||||||
if (!printer_query.get()) {
|
|
||||||
printer_query = queue_->CreatePrinterQuery(
|
|
||||||
content::ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE);
|
|
||||||
}
|
|
||||||
printer_query->SetSettings(
|
|
||||||
std::move(new_settings),
|
|
||||||
base::Bind(&PrintingMessageFilter::OnUpdatePrintSettingsReply, this,
|
|
||||||
printer_query, reply_msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintingMessageFilter::OnUpdatePrintSettingsReply(
|
|
||||||
scoped_refptr<PrinterQuery> printer_query,
|
|
||||||
IPC::Message* reply_msg) {
|
|
||||||
PrintMsg_PrintPages_Params params;
|
|
||||||
if (!printer_query.get() ||
|
|
||||||
printer_query->last_status() != PrintingContext::OK) {
|
|
||||||
params.Reset();
|
|
||||||
} else {
|
|
||||||
RenderParamsFromPrintSettings(printer_query->settings(), ¶ms.params);
|
|
||||||
params.params.document_cookie = printer_query->cookie();
|
|
||||||
params.pages = PageRange::GetPages(printer_query->settings().ranges());
|
|
||||||
}
|
|
||||||
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()) {
|
|
||||||
if (printer_query->cookie() && printer_query->settings().dpi()) {
|
|
||||||
queue_->QueuePrinterQuery(printer_query.get());
|
|
||||||
} else {
|
|
||||||
printer_query->StopWorker();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace printing
|
|
|
@ -1,97 +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 CHROME_BROWSER_PRINTING_PRINTING_MESSAGE_FILTER_H_
|
|
||||||
#define CHROME_BROWSER_PRINTING_PRINTING_MESSAGE_FILTER_H_
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "base/compiler_specific.h"
|
|
||||||
#include "content/public/browser/browser_message_filter.h"
|
|
||||||
|
|
||||||
struct PrintHostMsg_ScriptedPrint_Params;
|
|
||||||
|
|
||||||
namespace base {
|
|
||||||
class DictionaryValue;
|
|
||||||
class FilePath;
|
|
||||||
} // namespace base
|
|
||||||
|
|
||||||
namespace content {
|
|
||||||
class WebContents;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
class PrintQueriesQueue;
|
|
||||||
class PrinterQuery;
|
|
||||||
|
|
||||||
// This class filters out incoming printing related IPC messages for the
|
|
||||||
// renderer process on the IPC thread.
|
|
||||||
class PrintingMessageFilter : public content::BrowserMessageFilter {
|
|
||||||
public:
|
|
||||||
PrintingMessageFilter(int render_process_id);
|
|
||||||
|
|
||||||
// content::BrowserMessageFilter methods.
|
|
||||||
void OverrideThreadForMessage(const IPC::Message& message,
|
|
||||||
content::BrowserThread::ID* thread) override;
|
|
||||||
bool OnMessageReceived(const IPC::Message& message) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class base::DeleteHelper<PrintingMessageFilter>;
|
|
||||||
friend class content::BrowserThread;
|
|
||||||
|
|
||||||
~PrintingMessageFilter() override;
|
|
||||||
|
|
||||||
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_frame_id.
|
|
||||||
void UpdateFileDescriptor(int render_frame_id, int fd);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Get the default print setting.
|
|
||||||
void OnGetDefaultPrintSettings(IPC::Message* reply_msg);
|
|
||||||
|
|
||||||
// Set deviceName
|
|
||||||
void OnInitSettingWithDeviceName(const base::string16& device_name,
|
|
||||||
IPC::Message* reply_msg);
|
|
||||||
|
|
||||||
void OnGetDefaultPrintSettingsReply(scoped_refptr<PrinterQuery> printer_query,
|
|
||||||
IPC::Message* reply_msg);
|
|
||||||
|
|
||||||
// The renderer host have to show to the user the print dialog and returns
|
|
||||||
// the selected print settings. The task is handled by the print worker
|
|
||||||
// thread and the UI thread. The reply occurs on the IO thread.
|
|
||||||
void OnScriptedPrint(const PrintHostMsg_ScriptedPrint_Params& params,
|
|
||||||
IPC::Message* reply_msg);
|
|
||||||
void OnScriptedPrintReply(scoped_refptr<PrinterQuery> printer_query,
|
|
||||||
IPC::Message* reply_msg);
|
|
||||||
|
|
||||||
// Modify the current print settings based on |job_settings|. The task is
|
|
||||||
// handled by the print worker thread and the UI thread. The reply occurs on
|
|
||||||
// the IO thread.
|
|
||||||
void OnUpdatePrintSettings(int document_cookie,
|
|
||||||
const base::DictionaryValue& job_settings,
|
|
||||||
IPC::Message* reply_msg);
|
|
||||||
void OnUpdatePrintSettingsReply(scoped_refptr<PrinterQuery> printer_query,
|
|
||||||
IPC::Message* reply_msg);
|
|
||||||
|
|
||||||
const int render_process_id_;
|
|
||||||
|
|
||||||
scoped_refptr<PrintQueriesQueue> queue_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(PrintingMessageFilter);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace printing
|
|
||||||
|
|
||||||
#endif // CHROME_BROWSER_PRINTING_PRINTING_MESSAGE_FILTER_H_
|
|
|
@ -1,19 +0,0 @@
|
||||||
// Copyright 2013 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/printing/printing_ui_web_contents_observer.h"
|
|
||||||
|
|
||||||
#include "content/public/browser/browser_thread.h"
|
|
||||||
#include "content/public/browser/web_contents.h"
|
|
||||||
|
|
||||||
PrintingUIWebContentsObserver::PrintingUIWebContentsObserver(
|
|
||||||
content::WebContents* web_contents)
|
|
||||||
: content::WebContentsObserver(web_contents) {
|
|
||||||
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
|
|
||||||
}
|
|
||||||
|
|
||||||
gfx::NativeView PrintingUIWebContentsObserver::GetParentView() {
|
|
||||||
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
|
|
||||||
return web_contents() ? web_contents()->GetNativeView() : NULL;
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
// Copyright 2013 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_PRINTING_PRINTING_UI_WEB_CONTENTS_OBSERVER_H_
|
|
||||||
#define CHROME_BROWSER_PRINTING_PRINTING_UI_WEB_CONTENTS_OBSERVER_H_
|
|
||||||
|
|
||||||
#include "content/public/browser/web_contents_observer.h"
|
|
||||||
#include "ui/gfx/native_widget_types.h"
|
|
||||||
|
|
||||||
// Wrapper used to keep track of the lifetime of a WebContents.
|
|
||||||
// Lives on the UI thread.
|
|
||||||
class PrintingUIWebContentsObserver : public content::WebContentsObserver {
|
|
||||||
public:
|
|
||||||
explicit PrintingUIWebContentsObserver(content::WebContents* web_contents);
|
|
||||||
|
|
||||||
// Return the parent NativeView of the observed WebContents.
|
|
||||||
gfx::NativeView GetParentView();
|
|
||||||
|
|
||||||
private:
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(PrintingUIWebContentsObserver);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CHROME_BROWSER_PRINTING_PRINTING_UI_WEB_CONTENTS_OBSERVER_H_
|
|
|
@ -1,113 +0,0 @@
|
||||||
// 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/buildflags/buildflags.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.
|
|
||||||
#if 0
|
|
||||||
IPC_SYNC_MESSAGE_CONTROL2_0(ChromeUtilityHostMsg_PreCacheFontCharacters,
|
|
||||||
LOGFONT /* font_data */,
|
|
||||||
base::string16 /* characters */)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// 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
|
|
|
@ -1,66 +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 "chrome/common/print_messages.h"
|
|
||||||
|
|
||||||
#include "base/strings/string16.h"
|
|
||||||
#include "ui/gfx/geometry/size.h"
|
|
||||||
|
|
||||||
PrintMsg_Print_Params::PrintMsg_Print_Params()
|
|
||||||
: page_size(),
|
|
||||||
content_size(),
|
|
||||||
printable_area(),
|
|
||||||
margin_top(0),
|
|
||||||
margin_left(0),
|
|
||||||
dpi(0),
|
|
||||||
scale_factor(1.0f),
|
|
||||||
document_cookie(0),
|
|
||||||
selection_only(false),
|
|
||||||
supports_alpha_blend(false),
|
|
||||||
preview_ui_id(-1),
|
|
||||||
preview_request_id(0),
|
|
||||||
is_first_request(false),
|
|
||||||
print_scaling_option(blink::kWebPrintScalingOptionSourceSize),
|
|
||||||
print_to_pdf(false),
|
|
||||||
display_header_footer(false),
|
|
||||||
title(),
|
|
||||||
url(),
|
|
||||||
should_print_backgrounds(false) {}
|
|
||||||
|
|
||||||
PrintMsg_Print_Params::PrintMsg_Print_Params(const PrintMsg_Print_Params&) =
|
|
||||||
default;
|
|
||||||
PrintMsg_Print_Params::~PrintMsg_Print_Params() = default;
|
|
||||||
|
|
||||||
void PrintMsg_Print_Params::Reset() {
|
|
||||||
page_size = gfx::Size();
|
|
||||||
content_size = gfx::Size();
|
|
||||||
printable_area = gfx::Rect();
|
|
||||||
margin_top = 0;
|
|
||||||
margin_left = 0;
|
|
||||||
dpi = 0;
|
|
||||||
scale_factor = 1.0f;
|
|
||||||
document_cookie = 0;
|
|
||||||
selection_only = false;
|
|
||||||
supports_alpha_blend = false;
|
|
||||||
preview_ui_id = -1;
|
|
||||||
preview_request_id = 0;
|
|
||||||
is_first_request = false;
|
|
||||||
print_scaling_option = blink::kWebPrintScalingOptionSourceSize;
|
|
||||||
print_to_pdf = false;
|
|
||||||
display_header_footer = false;
|
|
||||||
title = base::string16();
|
|
||||||
url = base::string16();
|
|
||||||
should_print_backgrounds = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintMsg_PrintPages_Params::PrintMsg_PrintPages_Params() : pages() {}
|
|
||||||
PrintMsg_PrintPages_Params::PrintMsg_PrintPages_Params(
|
|
||||||
const PrintMsg_PrintPages_Params&) = default;
|
|
||||||
|
|
||||||
PrintMsg_PrintPages_Params::~PrintMsg_PrintPages_Params() = default;
|
|
||||||
|
|
||||||
void PrintMsg_PrintPages_Params::Reset() {
|
|
||||||
params.Reset();
|
|
||||||
pages = std::vector<int>();
|
|
||||||
}
|
|
|
@ -1,314 +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.
|
|
||||||
|
|
||||||
// IPC messages for printing.
|
|
||||||
// Multiply-included message file, hence no include guard.
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "base/memory/shared_memory.h"
|
|
||||||
#include "base/values.h"
|
|
||||||
#include "ipc/ipc_message_macros.h"
|
|
||||||
#include "printing/page_size_margins.h"
|
|
||||||
#include "printing/print_job_constants.h"
|
|
||||||
#include "third_party/blink/public/web/web_print_scaling_option.h"
|
|
||||||
#include "ui/gfx/geometry/rect.h"
|
|
||||||
#include "ui/gfx/native_widget_types.h"
|
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
#include "ipc/ipc_platform_file.h"
|
|
||||||
#include "printing/backend/print_backend.h"
|
|
||||||
#include "printing/page_range.h"
|
|
||||||
#include "printing/pdf_render_settings.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CHROME_COMMON_PRINT_MESSAGES_H_
|
|
||||||
#define CHROME_COMMON_PRINT_MESSAGES_H_
|
|
||||||
|
|
||||||
struct PrintMsg_Print_Params {
|
|
||||||
PrintMsg_Print_Params();
|
|
||||||
PrintMsg_Print_Params(const PrintMsg_Print_Params&);
|
|
||||||
~PrintMsg_Print_Params();
|
|
||||||
|
|
||||||
// Resets the members of the struct to 0.
|
|
||||||
void Reset();
|
|
||||||
|
|
||||||
gfx::Size page_size;
|
|
||||||
gfx::Size content_size;
|
|
||||||
gfx::Rect printable_area;
|
|
||||||
int margin_top;
|
|
||||||
int margin_left;
|
|
||||||
double dpi;
|
|
||||||
double scale_factor;
|
|
||||||
bool rasterize_pdf;
|
|
||||||
int document_cookie;
|
|
||||||
bool selection_only;
|
|
||||||
bool supports_alpha_blend;
|
|
||||||
int32_t preview_ui_id;
|
|
||||||
int preview_request_id;
|
|
||||||
bool is_first_request;
|
|
||||||
blink::WebPrintScalingOption print_scaling_option;
|
|
||||||
bool print_to_pdf;
|
|
||||||
bool display_header_footer;
|
|
||||||
base::string16 title;
|
|
||||||
base::string16 url;
|
|
||||||
bool should_print_backgrounds;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PrintMsg_PrintPages_Params {
|
|
||||||
PrintMsg_PrintPages_Params();
|
|
||||||
PrintMsg_PrintPages_Params(const PrintMsg_PrintPages_Params&);
|
|
||||||
~PrintMsg_PrintPages_Params();
|
|
||||||
|
|
||||||
// Resets the members of the struct to 0.
|
|
||||||
void Reset();
|
|
||||||
|
|
||||||
PrintMsg_Print_Params params;
|
|
||||||
std::vector<int> pages;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CHROME_COMMON_PRINT_MESSAGES_H_
|
|
||||||
|
|
||||||
#define IPC_MESSAGE_START PrintMsgStart
|
|
||||||
|
|
||||||
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::kWebPrintScalingOptionLast)
|
|
||||||
|
|
||||||
// Parameters for a render request.
|
|
||||||
IPC_STRUCT_TRAITS_BEGIN(PrintMsg_Print_Params)
|
|
||||||
// Physical size of the page, including non-printable margins,
|
|
||||||
// in pixels according to dpi.
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(page_size)
|
|
||||||
|
|
||||||
// In pixels according to dpi_x and dpi_y.
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(content_size)
|
|
||||||
|
|
||||||
// Physical printable area of the page in pixels according to dpi.
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(printable_area)
|
|
||||||
|
|
||||||
// The y-offset of the printable area, in pixels according to dpi.
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(margin_top)
|
|
||||||
|
|
||||||
// The x-offset of the printable area, in pixels according to dpi.
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(margin_left)
|
|
||||||
|
|
||||||
// Specifies dots per inch.
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(dpi)
|
|
||||||
|
|
||||||
// Specifies the scale factor in percent
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(scale_factor)
|
|
||||||
|
|
||||||
// Cookie for the document to ensure correctness.
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(document_cookie)
|
|
||||||
|
|
||||||
// Should only print currently selected text.
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(selection_only)
|
|
||||||
|
|
||||||
// Does the printer support alpha blending?
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(supports_alpha_blend)
|
|
||||||
|
|
||||||
// *** Parameters below are used only for print preview. ***
|
|
||||||
|
|
||||||
// The print preview ui associated with this request.
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(preview_ui_id)
|
|
||||||
|
|
||||||
// The id of the preview request.
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(preview_request_id)
|
|
||||||
|
|
||||||
// True if this is the first preview request.
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(is_first_request)
|
|
||||||
|
|
||||||
// Specifies the page scaling option for preview printing.
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(print_scaling_option)
|
|
||||||
|
|
||||||
// True if print to pdf is requested.
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(print_to_pdf)
|
|
||||||
|
|
||||||
// Specifies if the header and footer should be rendered.
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(display_header_footer)
|
|
||||||
|
|
||||||
// Title string to be printed as header if requested by the user.
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(title)
|
|
||||||
|
|
||||||
// URL string to be printed as footer if requested by the user.
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(url)
|
|
||||||
|
|
||||||
// True if print backgrounds is requested by the user.
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(should_print_backgrounds)
|
|
||||||
IPC_STRUCT_TRAITS_END()
|
|
||||||
|
|
||||||
IPC_STRUCT_BEGIN(PrintMsg_PrintPage_Params)
|
|
||||||
// Parameters to render the page as a printed page. It must always be the same
|
|
||||||
// value for all the document.
|
|
||||||
IPC_STRUCT_MEMBER(PrintMsg_Print_Params, params)
|
|
||||||
|
|
||||||
// The page number is the indicator of the square that should be rendered
|
|
||||||
// according to the layout specified in PrintMsg_Print_Params.
|
|
||||||
IPC_STRUCT_MEMBER(int, page_number)
|
|
||||||
IPC_STRUCT_END()
|
|
||||||
|
|
||||||
IPC_STRUCT_TRAITS_BEGIN(printing::PageSizeMargins)
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(content_width)
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(content_height)
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(margin_left)
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(margin_right)
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(margin_top)
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(margin_bottom)
|
|
||||||
IPC_STRUCT_TRAITS_END()
|
|
||||||
|
|
||||||
IPC_STRUCT_TRAITS_BEGIN(PrintMsg_PrintPages_Params)
|
|
||||||
// Parameters to render the page as a printed page. It must always be the same
|
|
||||||
// value for all the document.
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(params)
|
|
||||||
|
|
||||||
// If empty, this means a request to render all the printed pages.
|
|
||||||
IPC_STRUCT_TRAITS_MEMBER(pages)
|
|
||||||
IPC_STRUCT_TRAITS_END()
|
|
||||||
|
|
||||||
// Parameters to describe a rendered page.
|
|
||||||
IPC_STRUCT_BEGIN(PrintHostMsg_DidPrintPage_Params)
|
|
||||||
// A shared memory handle to the EMF data. This data can be quite large so a
|
|
||||||
// memory map needs to be used.
|
|
||||||
IPC_STRUCT_MEMBER(base::SharedMemoryHandle, metafile_data_handle)
|
|
||||||
|
|
||||||
// Size of the metafile data.
|
|
||||||
IPC_STRUCT_MEMBER(uint32_t, data_size)
|
|
||||||
|
|
||||||
// Cookie for the document to ensure correctness.
|
|
||||||
IPC_STRUCT_MEMBER(int, document_cookie)
|
|
||||||
|
|
||||||
// Page number.
|
|
||||||
IPC_STRUCT_MEMBER(int, page_number)
|
|
||||||
|
|
||||||
// Shrink factor used to render this page.
|
|
||||||
IPC_STRUCT_MEMBER(double, actual_shrink)
|
|
||||||
|
|
||||||
// The size of the page the page author specified.
|
|
||||||
IPC_STRUCT_MEMBER(gfx::Size, page_size)
|
|
||||||
|
|
||||||
// The printable area the page author specified.
|
|
||||||
IPC_STRUCT_MEMBER(gfx::Rect, content_area)
|
|
||||||
IPC_STRUCT_END()
|
|
||||||
|
|
||||||
// Parameters for the IPC message ViewHostMsg_ScriptedPrint
|
|
||||||
IPC_STRUCT_BEGIN(PrintHostMsg_ScriptedPrint_Params)
|
|
||||||
IPC_STRUCT_MEMBER(int, cookie)
|
|
||||||
IPC_STRUCT_MEMBER(int, expected_pages_count)
|
|
||||||
IPC_STRUCT_MEMBER(bool, has_selection)
|
|
||||||
IPC_STRUCT_MEMBER(printing::MarginType, margin_type)
|
|
||||||
IPC_STRUCT_END()
|
|
||||||
|
|
||||||
// Parameters to describe a rendered document.
|
|
||||||
IPC_STRUCT_BEGIN(PrintHostMsg_DidPreviewDocument_Params)
|
|
||||||
// A shared memory handle to metafile data.
|
|
||||||
IPC_STRUCT_MEMBER(base::SharedMemoryHandle, metafile_data_handle)
|
|
||||||
|
|
||||||
// Size of metafile data.
|
|
||||||
IPC_STRUCT_MEMBER(uint32_t, data_size)
|
|
||||||
|
|
||||||
// Cookie for the document to ensure correctness.
|
|
||||||
IPC_STRUCT_MEMBER(int, document_cookie)
|
|
||||||
|
|
||||||
// Store the expected pages count.
|
|
||||||
IPC_STRUCT_MEMBER(int, expected_pages_count)
|
|
||||||
|
|
||||||
// Whether the preview can be modified.
|
|
||||||
IPC_STRUCT_MEMBER(bool, modifiable)
|
|
||||||
|
|
||||||
// The id of the preview request.
|
|
||||||
IPC_STRUCT_MEMBER(int, preview_request_id)
|
|
||||||
IPC_STRUCT_END()
|
|
||||||
|
|
||||||
// Messages sent from the browser to the renderer.
|
|
||||||
|
|
||||||
// Tells the render view to switch the CSS to print media type, renders every
|
|
||||||
// requested pages and switch back the CSS to display media type.
|
|
||||||
IPC_MESSAGE_ROUTED3(PrintMsg_PrintPages,
|
|
||||||
bool /* silent print */,
|
|
||||||
bool /* print page's background */,
|
|
||||||
base::string16 /* device name*/)
|
|
||||||
|
|
||||||
// Tells the render view that printing is done so it can clean up.
|
|
||||||
IPC_MESSAGE_ROUTED1(PrintMsg_PrintingDone, bool /* success */)
|
|
||||||
|
|
||||||
// Tells the render view to switch the CSS to print media type, renders every
|
|
||||||
// requested pages for print preview using the given |settings|. This gets
|
|
||||||
// called multiple times as the user updates settings.
|
|
||||||
IPC_MESSAGE_ROUTED1(PrintMsg_PrintPreview, base::DictionaryValue /* settings */)
|
|
||||||
|
|
||||||
// Messages sent from the renderer to the browser.
|
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
// Duplicates a shared memory handle from the renderer to the browser. Then
|
|
||||||
// the renderer can flush the handle.
|
|
||||||
IPC_SYNC_MESSAGE_ROUTED1_1(PrintHostMsg_DuplicateSection,
|
|
||||||
base::SharedMemoryHandle /* renderer handle */,
|
|
||||||
base::SharedMemoryHandle /* browser handle */)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Tells the browser that the renderer is done calculating the number of
|
|
||||||
// rendered pages according to the specified settings.
|
|
||||||
IPC_MESSAGE_ROUTED2(PrintHostMsg_DidGetPrintedPagesCount,
|
|
||||||
int /* rendered document cookie */,
|
|
||||||
int /* number of rendered pages */)
|
|
||||||
|
|
||||||
// Sends the document cookie of the current printer query to the browser.
|
|
||||||
IPC_MESSAGE_ROUTED1(PrintHostMsg_DidGetDocumentCookie,
|
|
||||||
int /* rendered document cookie */)
|
|
||||||
|
|
||||||
// Tells the browser that the print dialog has been shown.
|
|
||||||
IPC_MESSAGE_ROUTED0(PrintHostMsg_DidShowPrintDialog)
|
|
||||||
|
|
||||||
// Sends back to the browser the rendered "printed page" that was requested by
|
|
||||||
// a ViewMsg_PrintPage message or from scripted printing. The memory handle in
|
|
||||||
// this message is already valid in the browser process.
|
|
||||||
IPC_MESSAGE_ROUTED1(PrintHostMsg_DidPrintPage,
|
|
||||||
PrintHostMsg_DidPrintPage_Params /* page content */)
|
|
||||||
|
|
||||||
// The renderer wants to know the default print settings.
|
|
||||||
IPC_SYNC_MESSAGE_ROUTED0_1(PrintHostMsg_GetDefaultPrintSettings,
|
|
||||||
PrintMsg_Print_Params /* default_settings */)
|
|
||||||
|
|
||||||
// you can set the printer
|
|
||||||
IPC_SYNC_MESSAGE_ROUTED1_1(PrintHostMsg_InitSettingWithDeviceName,
|
|
||||||
base::string16, /* device name */
|
|
||||||
PrintMsg_Print_Params /* default_settings */)
|
|
||||||
|
|
||||||
// The renderer wants to update the current print settings with new
|
|
||||||
// |job_settings|.
|
|
||||||
IPC_SYNC_MESSAGE_ROUTED2_2(PrintHostMsg_UpdatePrintSettings,
|
|
||||||
int /* document_cookie */,
|
|
||||||
base::DictionaryValue /* job_settings */,
|
|
||||||
PrintMsg_PrintPages_Params /* current_settings */,
|
|
||||||
bool /* canceled */)
|
|
||||||
|
|
||||||
// It's the renderer that controls the printing process when it is generated
|
|
||||||
// by javascript. This step is about showing UI to the user to select the
|
|
||||||
// final print settings. The output parameter is the same as
|
|
||||||
// ViewMsg_PrintPages which is executed implicitly.
|
|
||||||
IPC_SYNC_MESSAGE_ROUTED1_1(PrintHostMsg_ScriptedPrint,
|
|
||||||
PrintHostMsg_ScriptedPrint_Params,
|
|
||||||
PrintMsg_PrintPages_Params
|
|
||||||
/* settings chosen by the user*/)
|
|
||||||
|
|
||||||
// This is sent when there are invalid printer settings.
|
|
||||||
IPC_MESSAGE_ROUTED0(PrintHostMsg_ShowInvalidPrinterSettingsError)
|
|
||||||
|
|
||||||
// Tell the browser printing failed.
|
|
||||||
IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintingFailed, int /* document cookie */)
|
|
||||||
|
|
||||||
// Sends back to the browser the complete rendered document (non-draft mode,
|
|
||||||
// used for printing) that was requested by a PrintMsg_PrintPreview message.
|
|
||||||
// The memory handle in this message is already valid in the browser process.
|
|
||||||
IPC_MESSAGE_ROUTED1(PrintHostMsg_MetafileReadyForPrinting,
|
|
||||||
PrintHostMsg_DidPreviewDocument_Params /* params */)
|
|
||||||
|
|
||||||
IPC_MESSAGE_ROUTED2(PrintHostMsg_PrintPreviewFailed,
|
|
||||||
int /* document cookie */,
|
|
||||||
int /* request_id */);
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,396 +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 CHROME_RENDERER_PRINTING_PRINT_WEB_VIEW_HELPER_H_
|
|
||||||
#define CHROME_RENDERER_PRINTING_PRINT_WEB_VIEW_HELPER_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "base/callback.h"
|
|
||||||
#include "base/gtest_prod_util.h"
|
|
||||||
#include "base/memory/shared_memory.h"
|
|
||||||
#include "base/memory/weak_ptr.h"
|
|
||||||
#include "base/time/time.h"
|
|
||||||
#include "content/public/renderer/render_frame_observer.h"
|
|
||||||
#include "content/public/renderer/render_frame_observer_tracker.h"
|
|
||||||
#include "printing/pdf_metafile_skia.h"
|
|
||||||
#include "third_party/blink/public/web/web_local_frame.h"
|
|
||||||
#include "third_party/blink/public/web/web_node.h"
|
|
||||||
#include "third_party/blink/public/web/web_print_params.h"
|
|
||||||
#include "ui/gfx/geometry/size.h"
|
|
||||||
|
|
||||||
struct PrintMsg_Print_Params;
|
|
||||||
struct PrintMsg_PrintPage_Params;
|
|
||||||
struct PrintMsg_PrintPages_Params;
|
|
||||||
struct PrintHostMsg_SetOptionsFromDocument_Params;
|
|
||||||
|
|
||||||
namespace base {
|
|
||||||
class DictionaryValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace blink {
|
|
||||||
class WebView;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace cc {
|
|
||||||
class PaintCanvas;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
struct PageSizeMargins;
|
|
||||||
class PrepareFrameAndViewForPrint;
|
|
||||||
|
|
||||||
// Stores reference to frame using WebVew and unique name.
|
|
||||||
// Workaround to modal dialog issue on Linux. crbug.com/236147.
|
|
||||||
// If WebFrame someday supports WeakPtr, we should use it here.
|
|
||||||
class FrameReference {
|
|
||||||
public:
|
|
||||||
explicit FrameReference(blink::WebLocalFrame* frame);
|
|
||||||
FrameReference();
|
|
||||||
~FrameReference();
|
|
||||||
|
|
||||||
void Reset(blink::WebLocalFrame* frame);
|
|
||||||
|
|
||||||
blink::WebLocalFrame* GetFrame();
|
|
||||||
blink::WebView* view();
|
|
||||||
|
|
||||||
private:
|
|
||||||
blink::WebView* view_;
|
|
||||||
blink::WebLocalFrame* frame_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// PrintWebViewHelper handles most of the printing grunt work for RenderView.
|
|
||||||
// We plan on making print asynchronous and that will require copying the DOM
|
|
||||||
// of the document and creating a new WebView with the contents.
|
|
||||||
class PrintWebViewHelper
|
|
||||||
: public content::RenderFrameObserver,
|
|
||||||
public content::RenderFrameObserverTracker<PrintWebViewHelper> {
|
|
||||||
public:
|
|
||||||
explicit PrintWebViewHelper(content::RenderFrame* render_frame);
|
|
||||||
~PrintWebViewHelper() override;
|
|
||||||
|
|
||||||
void PrintNode(const blink::WebNode& node);
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum PrintingResult {
|
|
||||||
OK,
|
|
||||||
FAIL_PRINT_INIT,
|
|
||||||
FAIL_PRINT,
|
|
||||||
FAIL_PREVIEW,
|
|
||||||
INVALID_SETTINGS,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum PrintPreviewErrorBuckets {
|
|
||||||
PREVIEW_ERROR_NONE, // Always first.
|
|
||||||
PREVIEW_ERROR_BAD_SETTING,
|
|
||||||
PREVIEW_ERROR_METAFILE_COPY_FAILED,
|
|
||||||
PREVIEW_ERROR_METAFILE_INIT_FAILED_DEPRECATED,
|
|
||||||
PREVIEW_ERROR_ZERO_PAGES,
|
|
||||||
PREVIEW_ERROR_MAC_DRAFT_METAFILE_INIT_FAILED_DEPRECATED,
|
|
||||||
PREVIEW_ERROR_PAGE_RENDERED_WITHOUT_METAFILE,
|
|
||||||
PREVIEW_ERROR_INVALID_PRINTER_SETTINGS,
|
|
||||||
PREVIEW_ERROR_LAST_ENUM // Always last.
|
|
||||||
};
|
|
||||||
|
|
||||||
// RenderFrameObserver implementation.
|
|
||||||
bool OnMessageReceived(const IPC::Message& message) override;
|
|
||||||
void OnDestruct() override;
|
|
||||||
void ScriptedPrint(bool user_initiated) override;
|
|
||||||
|
|
||||||
// Message handlers ---------------------------------------------------------
|
|
||||||
#if !defined(DISABLE_BASIC_PRINTING)
|
|
||||||
void OnPrintPages(bool silent,
|
|
||||||
bool print_background,
|
|
||||||
const base::string16& device_name);
|
|
||||||
void OnPrintingDone(bool success);
|
|
||||||
#endif // !DISABLE_BASIC_PRINTING
|
|
||||||
void OnPrintPreview(const base::DictionaryValue& settings);
|
|
||||||
|
|
||||||
// Get |page_size| and |content_area| information from
|
|
||||||
// |page_layout_in_points|.
|
|
||||||
void GetPageSizeAndContentAreaFromPageLayout(
|
|
||||||
const PageSizeMargins& page_layout_in_points,
|
|
||||||
gfx::Size* page_size,
|
|
||||||
gfx::Rect* content_area);
|
|
||||||
|
|
||||||
// Update |ignore_css_margins_| based on settings.
|
|
||||||
void UpdateFrameMarginsCssInfo(const base::DictionaryValue& settings);
|
|
||||||
|
|
||||||
// Prepare frame for creating preview document.
|
|
||||||
void PrepareFrameForPreviewDocument();
|
|
||||||
|
|
||||||
// Continue creating preview document.
|
|
||||||
void OnFramePreparedForPreviewDocument();
|
|
||||||
|
|
||||||
// Finalize the print ready preview document.
|
|
||||||
bool FinalizePrintReadyDocument();
|
|
||||||
|
|
||||||
// Renders a print preview page. |page_number| is 0-based.
|
|
||||||
// Returns true if print preview should continue, false on failure.
|
|
||||||
bool RenderPreviewPage(int page_number,
|
|
||||||
const PrintMsg_Print_Params& print_params);
|
|
||||||
|
|
||||||
// Initialize the print preview document.
|
|
||||||
bool CreatePreviewDocument();
|
|
||||||
|
|
||||||
// Main printing code -------------------------------------------------------
|
|
||||||
|
|
||||||
void Print(blink::WebLocalFrame* frame,
|
|
||||||
const blink::WebNode& node,
|
|
||||||
bool silent = false,
|
|
||||||
bool print_background = false,
|
|
||||||
const base::string16& device_name = base::string16());
|
|
||||||
|
|
||||||
// Notification when printing is done - signal tear-down/free resources.
|
|
||||||
void DidFinishPrinting(PrintingResult result);
|
|
||||||
|
|
||||||
// Print Settings -----------------------------------------------------------
|
|
||||||
|
|
||||||
// Initialize print page settings with default settings.
|
|
||||||
// Used only for native printing workflow.
|
|
||||||
bool InitPrintSettings(bool fit_to_paper_size,
|
|
||||||
const base::string16& device_name = base::string16());
|
|
||||||
|
|
||||||
// Calculate number of pages in source document.
|
|
||||||
bool CalculateNumberOfPages(
|
|
||||||
blink::WebLocalFrame* frame,
|
|
||||||
const blink::WebNode& node,
|
|
||||||
int* number_of_pages,
|
|
||||||
const base::string16& device_name = base::string16());
|
|
||||||
|
|
||||||
// Update the current print settings with new |passed_job_settings|.
|
|
||||||
// |passed_job_settings| dictionary contains print job details such as printer
|
|
||||||
// name, number of copies, page range, etc.
|
|
||||||
bool UpdatePrintSettings(blink::WebLocalFrame* frame,
|
|
||||||
const blink::WebNode& node,
|
|
||||||
const base::DictionaryValue& passed_job_settings);
|
|
||||||
|
|
||||||
// Get final print settings from the user.
|
|
||||||
// Return false if the user cancels or on error.
|
|
||||||
bool GetPrintSettingsFromUser(blink::WebLocalFrame* frame,
|
|
||||||
const blink::WebNode& node,
|
|
||||||
int expected_pages_count);
|
|
||||||
|
|
||||||
// Page Printing / Rendering ------------------------------------------------
|
|
||||||
|
|
||||||
void OnFramePreparedForPrintPages();
|
|
||||||
void PrintPages();
|
|
||||||
bool PrintPagesNative(blink::WebLocalFrame* frame, int page_count);
|
|
||||||
void FinishFramePrinting();
|
|
||||||
|
|
||||||
// Prints the page listed in |params|.
|
|
||||||
#if defined(OS_LINUX) || defined(OS_ANDROID)
|
|
||||||
void PrintPageInternal(const PrintMsg_PrintPage_Params& params,
|
|
||||||
blink::WebLocalFrame* frame,
|
|
||||||
PdfMetafileSkia* metafile);
|
|
||||||
#elif defined(OS_WIN)
|
|
||||||
void PrintPageInternal(const PrintMsg_PrintPage_Params& params,
|
|
||||||
blink::WebLocalFrame* frame,
|
|
||||||
PdfMetafileSkia* metafile,
|
|
||||||
gfx::Size* page_size_in_dpi,
|
|
||||||
gfx::Rect* content_area_in_dpi);
|
|
||||||
#else
|
|
||||||
void PrintPageInternal(const PrintMsg_PrintPage_Params& params,
|
|
||||||
blink::WebLocalFrame* frame);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Render the frame for printing.
|
|
||||||
bool RenderPagesForPrint(blink::WebLocalFrame* frame,
|
|
||||||
const blink::WebNode& node);
|
|
||||||
|
|
||||||
// Platform specific helper function for rendering page(s) to |metafile|.
|
|
||||||
#if defined(OS_MACOSX)
|
|
||||||
void RenderPage(const PrintMsg_Print_Params& params,
|
|
||||||
int page_number,
|
|
||||||
blink::WebLocalFrame* frame,
|
|
||||||
PdfMetafileSkia* metafile,
|
|
||||||
gfx::Size* page_size,
|
|
||||||
gfx::Rect* content_rect);
|
|
||||||
#endif // defined(OS_MACOSX)
|
|
||||||
|
|
||||||
// Renders page contents from |frame| to |content_area| of |canvas|.
|
|
||||||
// |page_number| is zero-based.
|
|
||||||
// When method is called, canvas should be setup to draw to |canvas_area|
|
|
||||||
// with |scale_factor|.
|
|
||||||
static float RenderPageContent(blink::WebLocalFrame* frame,
|
|
||||||
int page_number,
|
|
||||||
const gfx::Rect& canvas_area,
|
|
||||||
const gfx::Rect& content_area,
|
|
||||||
double scale_factor,
|
|
||||||
cc::PaintCanvas* canvas);
|
|
||||||
|
|
||||||
// Helper methods -----------------------------------------------------------
|
|
||||||
|
|
||||||
bool CopyMetafileDataToSharedMem(const PdfMetafileSkia& metafile,
|
|
||||||
base::SharedMemoryHandle* shared_mem_handle);
|
|
||||||
|
|
||||||
// Helper method to get page layout in points and fit to page if needed.
|
|
||||||
static void ComputePageLayoutInPointsForCss(
|
|
||||||
blink::WebLocalFrame* frame,
|
|
||||||
int page_index,
|
|
||||||
const PrintMsg_Print_Params& default_params,
|
|
||||||
bool ignore_css_margins,
|
|
||||||
double* scale_factor,
|
|
||||||
PageSizeMargins* page_layout_in_points);
|
|
||||||
|
|
||||||
// Script Initiated Printing ------------------------------------------------
|
|
||||||
|
|
||||||
// Notifies the browser a print preview page has been rendered.
|
|
||||||
// |page_number| is 0-based.
|
|
||||||
// For a valid |page_number| with modifiable content,
|
|
||||||
// |metafile| is the rendered page. Otherwise |metafile| is NULL.
|
|
||||||
// Returns true if print preview should continue, false on failure.
|
|
||||||
bool PreviewPageRendered(int page_number, PdfMetafileSkia* metafile);
|
|
||||||
|
|
||||||
void SetPrintPagesParams(const PrintMsg_PrintPages_Params& settings);
|
|
||||||
|
|
||||||
// WebView used only to print the selection.
|
|
||||||
std::unique_ptr<PrepareFrameAndViewForPrint> prep_frame_view_;
|
|
||||||
bool reset_prep_frame_view_;
|
|
||||||
|
|
||||||
std::unique_ptr<PrintMsg_PrintPages_Params> print_pages_params_;
|
|
||||||
bool is_print_ready_metafile_sent_;
|
|
||||||
bool ignore_css_margins_;
|
|
||||||
|
|
||||||
// Used for scripted initiated printing blocking.
|
|
||||||
bool is_scripted_printing_blocked_;
|
|
||||||
|
|
||||||
// Let the browser process know of a printing failure. Only set to false when
|
|
||||||
// the failure came from the browser in the first place.
|
|
||||||
bool notify_browser_of_print_failure_;
|
|
||||||
|
|
||||||
// True, when printing from print preview.
|
|
||||||
bool print_for_preview_;
|
|
||||||
|
|
||||||
// Keeps track of the state of print preview between messages.
|
|
||||||
// TODO(vitalybuka): Create PrintPreviewContext when needed and delete after
|
|
||||||
// use. Now it's interaction with various messages is confusing.
|
|
||||||
class PrintPreviewContext {
|
|
||||||
public:
|
|
||||||
PrintPreviewContext();
|
|
||||||
~PrintPreviewContext();
|
|
||||||
|
|
||||||
// Initializes the print preview context. Need to be called to set
|
|
||||||
// the |web_frame| / |web_node| to generate the print preview for.
|
|
||||||
void InitWithFrame(blink::WebLocalFrame* web_frame);
|
|
||||||
void InitWithNode(const blink::WebNode& web_node);
|
|
||||||
|
|
||||||
// Does bookkeeping at the beginning of print preview.
|
|
||||||
void OnPrintPreview();
|
|
||||||
|
|
||||||
// Create the print preview document. |pages| is empty to print all pages.
|
|
||||||
// Takes ownership of |prepared_frame|.
|
|
||||||
bool CreatePreviewDocument(PrepareFrameAndViewForPrint* prepared_frame,
|
|
||||||
const std::vector<int>& pages);
|
|
||||||
|
|
||||||
// Called after a page gets rendered. |page_time| is how long the
|
|
||||||
// rendering took.
|
|
||||||
void RenderedPreviewPage(const base::TimeDelta& page_time);
|
|
||||||
|
|
||||||
// Updates the print preview context when the required pages are rendered.
|
|
||||||
void AllPagesRendered();
|
|
||||||
|
|
||||||
// Finalizes the print ready preview document.
|
|
||||||
void FinalizePrintReadyDocument();
|
|
||||||
|
|
||||||
// Cleanup after print preview finishes.
|
|
||||||
void Finished();
|
|
||||||
|
|
||||||
// Cleanup after print preview fails.
|
|
||||||
void Failed(bool report_error);
|
|
||||||
|
|
||||||
// Helper functions
|
|
||||||
int GetNextPageNumber();
|
|
||||||
bool IsRendering() const;
|
|
||||||
bool IsModifiable();
|
|
||||||
bool HasSelection();
|
|
||||||
bool IsLastPageOfPrintReadyMetafile() const;
|
|
||||||
bool IsFinalPageRendered() const;
|
|
||||||
|
|
||||||
// Setters
|
|
||||||
void set_generate_draft_pages(bool generate_draft_pages);
|
|
||||||
void set_error(enum PrintPreviewErrorBuckets error);
|
|
||||||
|
|
||||||
// Getters
|
|
||||||
// Original frame for which preview was requested.
|
|
||||||
blink::WebLocalFrame* source_frame();
|
|
||||||
// Original node for which preview was requested.
|
|
||||||
const blink::WebNode& source_node() const;
|
|
||||||
|
|
||||||
// Frame to be use to render preview. May be the same as source_frame(), or
|
|
||||||
// generated from it, e.g. copy of selected block.
|
|
||||||
blink::WebLocalFrame* prepared_frame();
|
|
||||||
// Node to be use to render preview. May be the same as source_node(), or
|
|
||||||
// generated from it, e.g. copy of selected block.
|
|
||||||
const blink::WebNode& prepared_node() const;
|
|
||||||
|
|
||||||
int total_page_count() const;
|
|
||||||
bool generate_draft_pages() const;
|
|
||||||
PdfMetafileSkia* metafile();
|
|
||||||
int last_error() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum State {
|
|
||||||
UNINITIALIZED, // Not ready to render.
|
|
||||||
INITIALIZED, // Ready to render.
|
|
||||||
RENDERING, // Rendering.
|
|
||||||
DONE // Finished rendering.
|
|
||||||
};
|
|
||||||
|
|
||||||
// Reset some of the internal rendering context.
|
|
||||||
void ClearContext();
|
|
||||||
|
|
||||||
// Specifies what to render for print preview.
|
|
||||||
FrameReference source_frame_;
|
|
||||||
blink::WebNode source_node_;
|
|
||||||
|
|
||||||
std::unique_ptr<PrepareFrameAndViewForPrint> prep_frame_view_;
|
|
||||||
std::unique_ptr<PdfMetafileSkia> metafile_;
|
|
||||||
|
|
||||||
// Total page count in the renderer.
|
|
||||||
int total_page_count_;
|
|
||||||
|
|
||||||
// The current page to render.
|
|
||||||
int current_page_index_;
|
|
||||||
|
|
||||||
// List of page indices that need to be rendered.
|
|
||||||
std::vector<int> pages_to_render_;
|
|
||||||
|
|
||||||
// True, when draft pages needs to be generated.
|
|
||||||
bool generate_draft_pages_;
|
|
||||||
|
|
||||||
// Specifies the total number of pages in the print ready metafile.
|
|
||||||
int print_ready_metafile_page_count_;
|
|
||||||
|
|
||||||
base::TimeDelta document_render_time_;
|
|
||||||
base::TimeTicks begin_time_;
|
|
||||||
|
|
||||||
enum PrintPreviewErrorBuckets error_;
|
|
||||||
|
|
||||||
State state_;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool print_node_in_progress_;
|
|
||||||
bool is_loading_;
|
|
||||||
bool is_scripted_preview_delayed_;
|
|
||||||
int ipc_nesting_level_;
|
|
||||||
|
|
||||||
PrintPreviewContext print_preview_context_;
|
|
||||||
|
|
||||||
// Used to fix a race condition where the source is a PDF and print preview
|
|
||||||
// hangs because RequestPrintPreview is called before DidStopLoading() is
|
|
||||||
// called. This is a store for the RequestPrintPreview() call and its
|
|
||||||
// parameters so that it can be invoked after DidStopLoading.
|
|
||||||
base::Closure on_stop_loading_closure_;
|
|
||||||
|
|
||||||
base::WeakPtrFactory<PrintWebViewHelper> weak_ptr_factory_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelper);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace printing
|
|
||||||
|
|
||||||
#endif // CHROME_RENDERER_PRINTING_PRINT_WEB_VIEW_HELPER_H_
|
|
|
@ -1,142 +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 "chrome/renderer/printing/print_web_view_helper.h"
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "base/logging.h"
|
|
||||||
#include "chrome/common/print_messages.h"
|
|
||||||
#include "content/public/renderer/render_thread.h"
|
|
||||||
#include "printing/metafile_skia_wrapper.h"
|
|
||||||
#include "printing/page_size_margins.h"
|
|
||||||
#include "printing/pdf_metafile_skia.h"
|
|
||||||
#include "third_party/blink/public/web/web_local_frame.h"
|
|
||||||
|
|
||||||
#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
|
|
||||||
#include "base/process/process_handle.h"
|
|
||||||
#else
|
|
||||||
#include "base/file_descriptor_posix.h"
|
|
||||||
#endif // !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
using blink::WebLocalFrame;
|
|
||||||
|
|
||||||
bool PrintWebViewHelper::RenderPreviewPage(
|
|
||||||
int page_number,
|
|
||||||
const PrintMsg_Print_Params& print_params) {
|
|
||||||
PrintMsg_PrintPage_Params page_params;
|
|
||||||
page_params.params = print_params;
|
|
||||||
page_params.page_number = page_number;
|
|
||||||
std::unique_ptr<PdfMetafileSkia> draft_metafile;
|
|
||||||
PdfMetafileSkia* initial_render_metafile = print_preview_context_.metafile();
|
|
||||||
if (print_preview_context_.IsModifiable() && is_print_ready_metafile_sent_) {
|
|
||||||
draft_metafile.reset(new PdfMetafileSkia());
|
|
||||||
initial_render_metafile = draft_metafile.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
base::TimeTicks begin_time = base::TimeTicks::Now();
|
|
||||||
PrintPageInternal(page_params, print_preview_context_.prepared_frame(),
|
|
||||||
initial_render_metafile);
|
|
||||||
print_preview_context_.RenderedPreviewPage(base::TimeTicks::Now() -
|
|
||||||
begin_time);
|
|
||||||
if (draft_metafile.get()) {
|
|
||||||
draft_metafile->FinishDocument();
|
|
||||||
} else if (print_preview_context_.IsModifiable() &&
|
|
||||||
print_preview_context_.generate_draft_pages()) {
|
|
||||||
DCHECK(!draft_metafile.get());
|
|
||||||
draft_metafile =
|
|
||||||
print_preview_context_.metafile()->GetMetafileForCurrentPage(
|
|
||||||
SkiaDocumentType::PDF);
|
|
||||||
}
|
|
||||||
return PreviewPageRendered(page_number, draft_metafile.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PrintWebViewHelper::PrintPagesNative(blink::WebLocalFrame* frame,
|
|
||||||
int page_count) {
|
|
||||||
PdfMetafileSkia metafile;
|
|
||||||
if (!metafile.Init())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const PrintMsg_PrintPages_Params& params = *print_pages_params_;
|
|
||||||
std::vector<int> printed_pages;
|
|
||||||
|
|
||||||
if (params.pages.empty()) {
|
|
||||||
for (int i = 0; i < page_count; ++i) {
|
|
||||||
printed_pages.push_back(i);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// TODO(vitalybuka): redesign to make more code cross platform.
|
|
||||||
for (size_t i = 0; i < params.pages.size(); ++i) {
|
|
||||||
if (params.pages[i] >= 0 && params.pages[i] < page_count) {
|
|
||||||
printed_pages.push_back(params.pages[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (printed_pages.empty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
PrintMsg_PrintPage_Params page_params;
|
|
||||||
page_params.params = params.params;
|
|
||||||
for (size_t i = 0; i < printed_pages.size(); ++i) {
|
|
||||||
page_params.page_number = printed_pages[i];
|
|
||||||
PrintPageInternal(page_params, frame, &metafile);
|
|
||||||
}
|
|
||||||
|
|
||||||
// blink::printEnd() for PDF should be called before metafile is closed.
|
|
||||||
FinishFramePrinting();
|
|
||||||
|
|
||||||
metafile.FinishDocument();
|
|
||||||
|
|
||||||
PrintHostMsg_DidPrintPage_Params printed_page_params;
|
|
||||||
if (!CopyMetafileDataToSharedMem(metafile,
|
|
||||||
&printed_page_params.metafile_data_handle)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
printed_page_params.data_size = metafile.GetDataSize();
|
|
||||||
printed_page_params.document_cookie = params.params.document_cookie;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < printed_pages.size(); ++i) {
|
|
||||||
printed_page_params.page_number = printed_pages[i];
|
|
||||||
Send(new PrintHostMsg_DidPrintPage(routing_id(), printed_page_params));
|
|
||||||
// Send the rest of the pages with an invalid metafile handle.
|
|
||||||
printed_page_params.metafile_data_handle.Release();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintWebViewHelper::PrintPageInternal(
|
|
||||||
const PrintMsg_PrintPage_Params& params,
|
|
||||||
WebLocalFrame* frame,
|
|
||||||
PdfMetafileSkia* metafile) {
|
|
||||||
PageSizeMargins page_layout_in_points;
|
|
||||||
double scale_factor = 1.0f;
|
|
||||||
ComputePageLayoutInPointsForCss(frame, params.page_number, params.params,
|
|
||||||
ignore_css_margins_, &scale_factor,
|
|
||||||
&page_layout_in_points);
|
|
||||||
gfx::Size page_size;
|
|
||||||
gfx::Rect content_area;
|
|
||||||
GetPageSizeAndContentAreaFromPageLayout(page_layout_in_points, &page_size,
|
|
||||||
&content_area);
|
|
||||||
gfx::Rect canvas_area = content_area;
|
|
||||||
|
|
||||||
cc::PaintCanvas* canvas =
|
|
||||||
metafile->GetVectorCanvasForNewPage(page_size, canvas_area, scale_factor);
|
|
||||||
if (!canvas)
|
|
||||||
return;
|
|
||||||
|
|
||||||
MetafileSkiaWrapper::SetMetafileOnCanvas(canvas, metafile);
|
|
||||||
|
|
||||||
RenderPageContent(frame, params.page_number, canvas_area, content_area,
|
|
||||||
scale_factor, canvas);
|
|
||||||
|
|
||||||
// Done printing. Close the device context to retrieve the compiled metafile.
|
|
||||||
if (!metafile->FinishPage())
|
|
||||||
NOTREACHED() << "metafile failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace printing
|
|
|
@ -1,127 +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 "chrome/renderer/printing/print_web_view_helper.h"
|
|
||||||
|
|
||||||
#import <AppKit/AppKit.h>
|
|
||||||
|
|
||||||
#include "base/logging.h"
|
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/metrics/histogram.h"
|
|
||||||
#include "cc/paint/paint_canvas.h"
|
|
||||||
#include "chrome/common/print_messages.h"
|
|
||||||
#include "printing/metafile_skia_wrapper.h"
|
|
||||||
#include "printing/page_size_margins.h"
|
|
||||||
#include "third_party/blink/public/web/web_local_frame.h"
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
using blink::WebLocalFrame;
|
|
||||||
|
|
||||||
void PrintWebViewHelper::PrintPageInternal(
|
|
||||||
const PrintMsg_PrintPage_Params& params,
|
|
||||||
WebLocalFrame* frame) {
|
|
||||||
PdfMetafileSkia metafile;
|
|
||||||
CHECK(metafile.Init());
|
|
||||||
|
|
||||||
int page_number = params.page_number;
|
|
||||||
gfx::Size page_size_in_dpi;
|
|
||||||
gfx::Rect content_area_in_dpi;
|
|
||||||
RenderPage(print_pages_params_->params, page_number, frame, &metafile,
|
|
||||||
&page_size_in_dpi, &content_area_in_dpi);
|
|
||||||
metafile.FinishDocument();
|
|
||||||
|
|
||||||
PrintHostMsg_DidPrintPage_Params page_params;
|
|
||||||
page_params.data_size = metafile.GetDataSize();
|
|
||||||
page_params.page_number = page_number;
|
|
||||||
page_params.document_cookie = params.params.document_cookie;
|
|
||||||
page_params.page_size = page_size_in_dpi;
|
|
||||||
page_params.content_area = content_area_in_dpi;
|
|
||||||
|
|
||||||
// Ask the browser to create the shared memory for us.
|
|
||||||
if (!CopyMetafileDataToSharedMem(metafile,
|
|
||||||
&(page_params.metafile_data_handle))) {
|
|
||||||
// TODO(thestig): Fail and return false instead.
|
|
||||||
page_params.data_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Send(new PrintHostMsg_DidPrintPage(routing_id(), page_params));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PrintWebViewHelper::RenderPreviewPage(
|
|
||||||
int page_number,
|
|
||||||
const PrintMsg_Print_Params& print_params) {
|
|
||||||
PrintMsg_Print_Params printParams = print_params;
|
|
||||||
std::unique_ptr<PdfMetafileSkia> draft_metafile;
|
|
||||||
PdfMetafileSkia* initial_render_metafile = print_preview_context_.metafile();
|
|
||||||
|
|
||||||
bool render_to_draft =
|
|
||||||
print_preview_context_.IsModifiable() && is_print_ready_metafile_sent_;
|
|
||||||
|
|
||||||
if (render_to_draft) {
|
|
||||||
draft_metafile.reset(new PdfMetafileSkia());
|
|
||||||
CHECK(draft_metafile->Init());
|
|
||||||
initial_render_metafile = draft_metafile.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
base::TimeTicks begin_time = base::TimeTicks::Now();
|
|
||||||
gfx::Size page_size;
|
|
||||||
RenderPage(printParams, page_number, print_preview_context_.prepared_frame(),
|
|
||||||
initial_render_metafile, &page_size, nullptr);
|
|
||||||
print_preview_context_.RenderedPreviewPage(base::TimeTicks::Now() -
|
|
||||||
begin_time);
|
|
||||||
|
|
||||||
if (draft_metafile.get()) {
|
|
||||||
draft_metafile->FinishDocument();
|
|
||||||
} else {
|
|
||||||
if (print_preview_context_.IsModifiable() &&
|
|
||||||
print_preview_context_.generate_draft_pages()) {
|
|
||||||
DCHECK(!draft_metafile.get());
|
|
||||||
draft_metafile =
|
|
||||||
print_preview_context_.metafile()->GetMetafileForCurrentPage(
|
|
||||||
SkiaDocumentType::PDF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return PreviewPageRendered(page_number, draft_metafile.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintWebViewHelper::RenderPage(const PrintMsg_Print_Params& params,
|
|
||||||
int page_number,
|
|
||||||
WebLocalFrame* frame,
|
|
||||||
PdfMetafileSkia* metafile,
|
|
||||||
gfx::Size* page_size,
|
|
||||||
gfx::Rect* content_rect) {
|
|
||||||
double scale_factor = 1.0f;
|
|
||||||
double webkit_shrink_factor = frame->GetPrintPageShrink(page_number);
|
|
||||||
PageSizeMargins page_layout_in_points;
|
|
||||||
gfx::Rect content_area;
|
|
||||||
|
|
||||||
ComputePageLayoutInPointsForCss(frame, page_number, params,
|
|
||||||
ignore_css_margins_, &scale_factor,
|
|
||||||
&page_layout_in_points);
|
|
||||||
GetPageSizeAndContentAreaFromPageLayout(page_layout_in_points, page_size,
|
|
||||||
&content_area);
|
|
||||||
if (content_rect)
|
|
||||||
*content_rect = content_area;
|
|
||||||
|
|
||||||
scale_factor *= webkit_shrink_factor;
|
|
||||||
|
|
||||||
gfx::Rect canvas_area = content_area;
|
|
||||||
|
|
||||||
{
|
|
||||||
cc::PaintCanvas* canvas = metafile->GetVectorCanvasForNewPage(
|
|
||||||
*page_size, canvas_area, scale_factor);
|
|
||||||
if (!canvas)
|
|
||||||
return;
|
|
||||||
|
|
||||||
MetafileSkiaWrapper::SetMetafileOnCanvas(canvas, metafile);
|
|
||||||
RenderPageContent(frame, page_number, canvas_area, content_area,
|
|
||||||
scale_factor, static_cast<cc::PaintCanvas*>(canvas));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Done printing. Close the device context to retrieve the compiled metafile.
|
|
||||||
metafile->FinishPage();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace printing
|
|
|
@ -1,207 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#include "chrome/renderer/printing/print_web_view_helper.h"
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "base/logging.h"
|
|
||||||
#include "base/process/process_handle.h"
|
|
||||||
#include "chrome/common/print_messages.h"
|
|
||||||
#include "content/public/renderer/render_thread.h"
|
|
||||||
#include "printing/metafile_skia_wrapper.h"
|
|
||||||
#include "printing/page_size_margins.h"
|
|
||||||
#include "printing/pdf_metafile_skia.h"
|
|
||||||
#include "printing/units.h"
|
|
||||||
#include "third_party/blink/public/web/web_local_frame.h"
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
using blink::WebLocalFrame;
|
|
||||||
|
|
||||||
bool PrintWebViewHelper::RenderPreviewPage(
|
|
||||||
int page_number,
|
|
||||||
const PrintMsg_Print_Params& print_params) {
|
|
||||||
PrintMsg_PrintPage_Params page_params;
|
|
||||||
page_params.params = print_params;
|
|
||||||
page_params.page_number = page_number;
|
|
||||||
std::unique_ptr<PdfMetafileSkia> draft_metafile;
|
|
||||||
PdfMetafileSkia* initial_render_metafile = print_preview_context_.metafile();
|
|
||||||
if (print_preview_context_.IsModifiable() && is_print_ready_metafile_sent_) {
|
|
||||||
draft_metafile.reset(new PdfMetafileSkia());
|
|
||||||
initial_render_metafile = draft_metafile.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
base::TimeTicks begin_time = base::TimeTicks::Now();
|
|
||||||
PrintPageInternal(page_params, print_preview_context_.prepared_frame(),
|
|
||||||
initial_render_metafile, NULL, NULL);
|
|
||||||
print_preview_context_.RenderedPreviewPage(base::TimeTicks::Now() -
|
|
||||||
begin_time);
|
|
||||||
if (draft_metafile.get()) {
|
|
||||||
draft_metafile->FinishDocument();
|
|
||||||
} else if (print_preview_context_.IsModifiable() &&
|
|
||||||
print_preview_context_.generate_draft_pages()) {
|
|
||||||
DCHECK(!draft_metafile.get());
|
|
||||||
draft_metafile =
|
|
||||||
print_preview_context_.metafile()->GetMetafileForCurrentPage(
|
|
||||||
SkiaDocumentType::PDF);
|
|
||||||
}
|
|
||||||
return PreviewPageRendered(page_number, draft_metafile.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PrintWebViewHelper::PrintPagesNative(blink::WebLocalFrame* frame,
|
|
||||||
int page_count) {
|
|
||||||
PdfMetafileSkia metafile;
|
|
||||||
if (!metafile.Init())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const PrintMsg_PrintPages_Params& params = *print_pages_params_;
|
|
||||||
std::vector<int> printed_pages;
|
|
||||||
if (params.pages.empty()) {
|
|
||||||
for (int i = 0; i < page_count; ++i) {
|
|
||||||
printed_pages.push_back(i);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// TODO(vitalybuka): redesign to make more code cross platform.
|
|
||||||
for (size_t i = 0; i < params.pages.size(); ++i) {
|
|
||||||
if (params.pages[i] >= 0 && params.pages[i] < page_count) {
|
|
||||||
printed_pages.push_back(params.pages[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (printed_pages.empty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::vector<gfx::Size> page_size_in_dpi(printed_pages.size());
|
|
||||||
std::vector<gfx::Rect> content_area_in_dpi(printed_pages.size());
|
|
||||||
|
|
||||||
PrintMsg_PrintPage_Params page_params;
|
|
||||||
page_params.params = params.params;
|
|
||||||
for (size_t i = 0; i < printed_pages.size(); ++i) {
|
|
||||||
page_params.page_number = printed_pages[i];
|
|
||||||
PrintPageInternal(page_params, frame, &metafile, &page_size_in_dpi[i],
|
|
||||||
&content_area_in_dpi[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// blink::printEnd() for PDF should be called before metafile is closed.
|
|
||||||
FinishFramePrinting();
|
|
||||||
|
|
||||||
metafile.FinishDocument();
|
|
||||||
|
|
||||||
PrintHostMsg_DidPrintPage_Params printed_page_params;
|
|
||||||
if (!CopyMetafileDataToSharedMem(metafile,
|
|
||||||
&printed_page_params.metafile_data_handle)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
printed_page_params.content_area = params.params.printable_area;
|
|
||||||
printed_page_params.data_size = metafile.GetDataSize();
|
|
||||||
printed_page_params.document_cookie = params.params.document_cookie;
|
|
||||||
printed_page_params.page_size = params.params.page_size;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < printed_pages.size(); ++i) {
|
|
||||||
printed_page_params.page_number = printed_pages[i];
|
|
||||||
printed_page_params.page_size = page_size_in_dpi[i];
|
|
||||||
printed_page_params.content_area = content_area_in_dpi[i];
|
|
||||||
Send(new PrintHostMsg_DidPrintPage(routing_id(), printed_page_params));
|
|
||||||
// Send the rest of the pages with an invalid metafile handle.
|
|
||||||
printed_page_params.metafile_data_handle.Close();
|
|
||||||
printed_page_params.metafile_data_handle = base::SharedMemoryHandle();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintWebViewHelper::PrintPageInternal(
|
|
||||||
const PrintMsg_PrintPage_Params& params,
|
|
||||||
WebLocalFrame* frame,
|
|
||||||
PdfMetafileSkia* metafile,
|
|
||||||
gfx::Size* page_size_in_dpi,
|
|
||||||
gfx::Rect* content_area_in_dpi) {
|
|
||||||
PageSizeMargins page_layout_in_points;
|
|
||||||
double css_scale_factor = 1.0f;
|
|
||||||
ComputePageLayoutInPointsForCss(frame, params.page_number, params.params,
|
|
||||||
ignore_css_margins_, &css_scale_factor,
|
|
||||||
&page_layout_in_points);
|
|
||||||
gfx::Size page_size;
|
|
||||||
gfx::Rect content_area;
|
|
||||||
GetPageSizeAndContentAreaFromPageLayout(page_layout_in_points, &page_size,
|
|
||||||
&content_area);
|
|
||||||
int dpi = static_cast<int>(params.params.dpi);
|
|
||||||
// Calculate the actual page size and content area in dpi.
|
|
||||||
if (page_size_in_dpi) {
|
|
||||||
*page_size_in_dpi =
|
|
||||||
gfx::Size(static_cast<int>(ConvertUnitDouble(page_size.width(),
|
|
||||||
kPointsPerInch, dpi)),
|
|
||||||
static_cast<int>(ConvertUnitDouble(page_size.height(),
|
|
||||||
kPointsPerInch, dpi)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (content_area_in_dpi) {
|
|
||||||
// Output PDF matches paper size and should be printer edge to edge.
|
|
||||||
*content_area_in_dpi =
|
|
||||||
gfx::Rect(0, 0, page_size_in_dpi->width(), page_size_in_dpi->height());
|
|
||||||
}
|
|
||||||
|
|
||||||
gfx::Rect canvas_area = content_area;
|
|
||||||
#if 0
|
|
||||||
params.params.display_header_footer ? gfx::Rect(page_size) : content_area;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
float webkit_page_shrink_factor =
|
|
||||||
frame->GetPrintPageShrink(params.page_number);
|
|
||||||
float scale_factor = css_scale_factor * webkit_page_shrink_factor;
|
|
||||||
|
|
||||||
cc::PaintCanvas* canvas =
|
|
||||||
metafile->GetVectorCanvasForNewPage(page_size, canvas_area, scale_factor);
|
|
||||||
if (!canvas)
|
|
||||||
return;
|
|
||||||
|
|
||||||
MetafileSkiaWrapper::SetMetafileOnCanvas(canvas, metafile);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (params.params.display_header_footer) {
|
|
||||||
// |page_number| is 0-based, so 1 is added.
|
|
||||||
PrintHeaderAndFooter(canvas.get(),
|
|
||||||
params.page_number + 1,
|
|
||||||
print_preview_context_.total_page_count(),
|
|
||||||
*frame,
|
|
||||||
scale_factor,
|
|
||||||
page_layout_in_points,
|
|
||||||
params.params);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
float webkit_scale_factor =
|
|
||||||
RenderPageContent(frame, params.page_number, canvas_area, content_area,
|
|
||||||
scale_factor, canvas);
|
|
||||||
DCHECK_GT(webkit_scale_factor, 0.0f);
|
|
||||||
// Done printing. Close the device context to retrieve the compiled metafile.
|
|
||||||
if (!metafile->FinishPage())
|
|
||||||
NOTREACHED() << "metafile failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PrintWebViewHelper::CopyMetafileDataToSharedMem(
|
|
||||||
const PdfMetafileSkia& metafile,
|
|
||||||
base::SharedMemoryHandle* shared_mem_handle) {
|
|
||||||
uint32_t buf_size = metafile.GetDataSize();
|
|
||||||
if (buf_size == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::unique_ptr<base::SharedMemory> shared_buf(
|
|
||||||
content::RenderThread::Get()->HostAllocateSharedMemoryBuffer(buf_size));
|
|
||||||
if (!shared_buf)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!shared_buf->Map(buf_size))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!metafile.GetData(shared_buf->memory(), buf_size))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
*shared_mem_handle =
|
|
||||||
base::SharedMemory::DuplicateHandle(shared_buf->handle());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace printing
|
|
|
@ -1,176 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#include "chrome/utility/printing_handler_win.h"
|
|
||||||
|
|
||||||
#include "base/files/file_util.h"
|
|
||||||
#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"
|
|
||||||
#include "printing/emf_win.h"
|
|
||||||
#include "printing/page_range.h"
|
|
||||||
#include "printing/pdf_render_settings.h"
|
|
||||||
#include "ui/gfx/gdi_util.h"
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
bool Send(IPC::Message* message) {
|
|
||||||
return content::UtilityThread::Get()->Send(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReleaseProcessIfNeeded() {
|
|
||||||
content::UtilityThread::Get()->ReleaseProcess();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PreCacheFontCharacters(const LOGFONT* logfont,
|
|
||||||
const wchar_t* text,
|
|
||||||
size_t text_length) {
|
|
||||||
#if 0
|
|
||||||
Send(new ChromeUtilityHostMsg_PreCacheFontCharacters(
|
|
||||||
*logfont, base::string16(text, text_length)));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
PrintingHandlerWin::PrintingHandlerWin() {
|
|
||||||
chrome_pdf::SetPDFEnsureTypefaceCharactersAccessible(PreCacheFontCharacters);
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintingHandlerWin::~PrintingHandlerWin() {}
|
|
||||||
|
|
||||||
bool PrintingHandlerWin::OnMessageReceived(const IPC::Message& message) {
|
|
||||||
bool handled = true;
|
|
||||||
IPC_BEGIN_MESSAGE_MAP(PrintingHandlerWin, message)
|
|
||||||
IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToMetafiles,
|
|
||||||
OnRenderPDFPagesToMetafile)
|
|
||||||
IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage,
|
|
||||||
OnRenderPDFPagesToMetafileGetPage)
|
|
||||||
IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop,
|
|
||||||
OnRenderPDFPagesToMetafileStop)
|
|
||||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
|
||||||
IPC_END_MESSAGE_MAP()
|
|
||||||
return handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintingHandlerWin::OnRenderPDFPagesToMetafile(
|
|
||||||
IPC::PlatformFileForTransit pdf_transit,
|
|
||||||
const PdfRenderSettings& settings) {
|
|
||||||
pdf_rendering_settings_ = settings;
|
|
||||||
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 = chrome_pdf::PrintingMode::kPostScript2;
|
|
||||||
break;
|
|
||||||
case PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3:
|
|
||||||
postscript_level = chrome_pdf::PrintingMode::kPostScript3;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
postscript_level =
|
|
||||||
chrome_pdf::PrintingMode::kEmf; // Not using postscript.
|
|
||||||
}
|
|
||||||
chrome_pdf::SetPDFUsePrintMode(postscript_level);
|
|
||||||
|
|
||||||
base::File pdf_file = IPC::PlatformFileForTransitToFile(pdf_transit);
|
|
||||||
int page_count = LoadPDF(std::move(pdf_file));
|
|
||||||
Send(
|
|
||||||
new ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount(page_count));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintingHandlerWin::OnRenderPDFPagesToMetafileGetPage(
|
|
||||||
int page_number,
|
|
||||||
IPC::PlatformFileForTransit output_file) {
|
|
||||||
base::File emf_file = IPC::PlatformFileForTransitToFile(output_file);
|
|
||||||
float scale_factor = 1.0f;
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintingHandlerWin::OnRenderPDFPagesToMetafileStop() {
|
|
||||||
ReleaseProcessIfNeeded();
|
|
||||||
}
|
|
||||||
|
|
||||||
int PrintingHandlerWin::LoadPDF(base::File pdf_file) {
|
|
||||||
int64_t length64 = pdf_file.GetLength();
|
|
||||||
if (length64 <= 0 || length64 > std::numeric_limits<int>::max())
|
|
||||||
return 0;
|
|
||||||
int length = static_cast<int>(length64);
|
|
||||||
|
|
||||||
pdf_data_.resize(length);
|
|
||||||
if (length != pdf_file.Read(0, pdf_data_.data(), pdf_data_.size()))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
int total_page_count = 0;
|
|
||||||
if (!chrome_pdf::GetPDFDocInfo(&pdf_data_.front(), pdf_data_.size(),
|
|
||||||
&total_page_count, nullptr)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return total_page_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PrintingHandlerWin::RenderPdfPageToMetafile(int page_number,
|
|
||||||
base::File output_file,
|
|
||||||
float* scale_factor,
|
|
||||||
bool postscript) {
|
|
||||||
Emf metafile;
|
|
||||||
metafile.Init();
|
|
||||||
|
|
||||||
// We need to scale down DC to fit an entire page into DC available area.
|
|
||||||
// Current metafile is based on screen DC and have current screen size.
|
|
||||||
// Writing outside of those boundaries will result in the cut-off output.
|
|
||||||
// On metafiles (this is the case here), scaling down will still record
|
|
||||||
// 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).
|
|
||||||
//
|
|
||||||
// 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.width(),
|
|
||||||
pdf_rendering_settings_.dpi.height(),
|
|
||||||
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_.use_color,
|
|
||||||
pdf_rendering_settings_.autorotate)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
metafile.FinishPage();
|
|
||||||
metafile.FinishDocument();
|
|
||||||
return metafile.SaveTo(&output_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace printing
|
|
|
@ -1,52 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#ifndef CHROME_UTILITY_PRINTING_HANDLER_WIN_H_
|
|
||||||
#define CHROME_UTILITY_PRINTING_HANDLER_WIN_H_
|
|
||||||
|
|
||||||
#include "base/compiler_specific.h"
|
|
||||||
#include "base/macros.h"
|
|
||||||
#include "chrome/utility/utility_message_handler.h"
|
|
||||||
#include "ipc/ipc_platform_file.h"
|
|
||||||
#include "printing/pdf_render_settings.h"
|
|
||||||
|
|
||||||
namespace printing {
|
|
||||||
|
|
||||||
struct PdfRenderSettings;
|
|
||||||
struct PwgRasterSettings;
|
|
||||||
struct PageRange;
|
|
||||||
|
|
||||||
// Dispatches IPCs for printing.
|
|
||||||
class PrintingHandlerWin : public UtilityMessageHandler {
|
|
||||||
public:
|
|
||||||
PrintingHandlerWin();
|
|
||||||
~PrintingHandlerWin() override;
|
|
||||||
|
|
||||||
// IPC::Listener:
|
|
||||||
bool OnMessageReceived(const IPC::Message& message) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// IPC message handlers.
|
|
||||||
void OnRenderPDFPagesToMetafile(IPC::PlatformFileForTransit pdf_transit,
|
|
||||||
const PdfRenderSettings& settings);
|
|
||||||
void OnRenderPDFPagesToMetafileGetPage(
|
|
||||||
int page_number,
|
|
||||||
IPC::PlatformFileForTransit output_file);
|
|
||||||
void OnRenderPDFPagesToMetafileStop();
|
|
||||||
|
|
||||||
int LoadPDF(base::File pdf_file);
|
|
||||||
bool RenderPdfPageToMetafile(int page_number,
|
|
||||||
base::File output_file,
|
|
||||||
float* scale_factor,
|
|
||||||
bool postscript);
|
|
||||||
|
|
||||||
std::vector<char> pdf_data_;
|
|
||||||
PdfRenderSettings pdf_rendering_settings_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(PrintingHandlerWin);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace printing
|
|
||||||
|
|
||||||
#endif // CHROME_UTILITY_PRINTING_HANDLER_WIN_H_
|
|
|
@ -1,21 +0,0 @@
|
||||||
// Copyright 2013 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_UTILITY_UTILITY_MESSAGE_HANDLER_H_
|
|
||||||
#define CHROME_UTILITY_UTILITY_MESSAGE_HANDLER_H_
|
|
||||||
|
|
||||||
namespace IPC {
|
|
||||||
class Message;
|
|
||||||
}
|
|
||||||
|
|
||||||
class UtilityMessageHandler {
|
|
||||||
public:
|
|
||||||
virtual ~UtilityMessageHandler() {}
|
|
||||||
|
|
||||||
// Called when a message is received. Returns true iff the message was
|
|
||||||
// handled.
|
|
||||||
virtual bool OnMessageReceived(const IPC::Message& message) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CHROME_UTILITY_UTILITY_MESSAGE_HANDLER_H_
|
|
|
@ -5,6 +5,17 @@
|
||||||
V8 Proxy Resolver
|
V8 Proxy Resolver
|
||||||
</message>
|
</message>
|
||||||
|
|
||||||
|
<!-- Printing Service -->
|
||||||
|
<message name="IDS_UTILITY_PROCESS_PRINTING_SERVICE_NAME" desc="The name of the utility process used for printing conversions.">
|
||||||
|
Printing Service
|
||||||
|
</message>
|
||||||
|
<message name="IDS_PRINT_INVALID_PRINTER_SETTINGS" desc="Message to display when selected printer is not reachable or its settings are invalid.">
|
||||||
|
The selected printer is not available or not installed correctly. <ph name="BR"><br></ph> Check your printer or try selecting another printer.
|
||||||
|
</message>
|
||||||
|
<message name="IDS_DEFAULT_PRINT_DOCUMENT_TITLE" desc="Default title for a print document">
|
||||||
|
Untitled Document
|
||||||
|
</message>
|
||||||
|
|
||||||
<!-- Desktop Capturer API -->
|
<!-- Desktop Capturer API -->
|
||||||
<message name="IDS_DESKTOP_MEDIA_PICKER_SINGLE_SCREEN_NAME" desc="Name for screens in the desktop media picker UI when there is only one monitor.">
|
<message name="IDS_DESKTOP_MEDIA_PICKER_SINGLE_SCREEN_NAME" desc="Name for screens in the desktop media picker UI when there is only one monitor.">
|
||||||
Entire screen
|
Entire screen
|
||||||
|
|
|
@ -582,40 +582,13 @@ filenames = {
|
||||||
"chromium_src/chrome/browser/chrome_process_finder_win.cc",
|
"chromium_src/chrome/browser/chrome_process_finder_win.cc",
|
||||||
"chromium_src/chrome/browser/chrome_process_finder_win.h",
|
"chromium_src/chrome/browser/chrome_process_finder_win.h",
|
||||||
"chromium_src/chrome/browser/chrome_notification_types.h",
|
"chromium_src/chrome/browser/chrome_notification_types.h",
|
||||||
"chromium_src/chrome/browser/printing/print_job.cc",
|
|
||||||
"chromium_src/chrome/browser/printing/print_job.h",
|
|
||||||
"chromium_src/chrome/browser/printing/print_job_manager.cc",
|
|
||||||
"chromium_src/chrome/browser/printing/print_job_manager.h",
|
|
||||||
"chromium_src/chrome/browser/printing/print_job_worker.cc",
|
|
||||||
"chromium_src/chrome/browser/printing/print_job_worker.h",
|
|
||||||
"chromium_src/chrome/browser/printing/print_job_worker_owner.cc",
|
|
||||||
"chromium_src/chrome/browser/printing/print_job_worker_owner.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/print_view_manager_basic.cc",
|
|
||||||
"chromium_src/chrome/browser/printing/print_view_manager_basic.h",
|
|
||||||
"chromium_src/chrome/browser/printing/print_view_manager_observer.h",
|
|
||||||
"chromium_src/chrome/browser/printing/printer_query.cc",
|
|
||||||
"chromium_src/chrome/browser/printing/printer_query.h",
|
|
||||||
"chromium_src/chrome/browser/printing/printing_message_filter.cc",
|
|
||||||
"chromium_src/chrome/browser/printing/printing_message_filter.h",
|
|
||||||
"chromium_src/chrome/browser/printing/print_preview_message_handler.cc",
|
|
||||||
"chromium_src/chrome/browser/printing/print_preview_message_handler.h",
|
|
||||||
"chromium_src/chrome/browser/process_singleton_posix.cc",
|
"chromium_src/chrome/browser/process_singleton_posix.cc",
|
||||||
"chromium_src/chrome/browser/process_singleton_win.cc",
|
"chromium_src/chrome/browser/process_singleton_win.cc",
|
||||||
"chromium_src/chrome/browser/process_singleton.h",
|
"chromium_src/chrome/browser/process_singleton.h",
|
||||||
"chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.cc",
|
"chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.cc",
|
||||||
"chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h",
|
"chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h",
|
||||||
"chromium_src/chrome/common/print_messages.cc",
|
|
||||||
"chromium_src/chrome/common/print_messages.h",
|
|
||||||
"chromium_src/chrome/renderer/printing/print_web_view_helper.cc",
|
|
||||||
"chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc",
|
|
||||||
"chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm",
|
|
||||||
"chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc",
|
|
||||||
"chromium_src/chrome/renderer/printing/print_web_view_helper.h",
|
|
||||||
"chromium_src/chrome/renderer/spellchecker/spellcheck_worditerator.cc",
|
"chromium_src/chrome/renderer/spellchecker/spellcheck_worditerator.cc",
|
||||||
"chromium_src/chrome/renderer/spellchecker/spellcheck_worditerator.h",
|
"chromium_src/chrome/renderer/spellchecker/spellcheck_worditerator.h",
|
||||||
"chromium_src/chrome/utility/utility_message_handler.h",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
lib_sources_nss = [
|
lib_sources_nss = [
|
||||||
|
@ -623,13 +596,6 @@ filenames = {
|
||||||
"chromium_src/chrome/browser/certificate_manager_model.h",
|
"chromium_src/chrome/browser/certificate_manager_model.h",
|
||||||
]
|
]
|
||||||
|
|
||||||
lib_sources_win = [
|
|
||||||
"chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc",
|
|
||||||
"chromium_src/chrome/browser/printing/pdf_to_emf_converter.h",
|
|
||||||
"chromium_src/chrome/utility/printing_handler_win.cc",
|
|
||||||
"chromium_src/chrome/utility/printing_handler_win.h",
|
|
||||||
]
|
|
||||||
|
|
||||||
app_sources = [
|
app_sources = [
|
||||||
"atom/app/atom_main.cc",
|
"atom/app/atom_main.cc",
|
||||||
"atom/app/atom_main.h",
|
"atom/app/atom_main.h",
|
||||||
|
|
|
@ -249,6 +249,8 @@ WebContents.prototype.printToPDF = function (options, callback) {
|
||||||
printingSetting.mediaSize = PDFPageSizes['A4']
|
printingSetting.mediaSize = PDFPageSizes['A4']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Chromium expects this in a 0-100 range number, not as float
|
||||||
|
printingSetting.scaleFactor *= 100
|
||||||
this._printToPDF(printingSetting, callback)
|
this._printToPDF(printingSetting, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
"service_manager:connector": {
|
"service_manager:connector": {
|
||||||
"requires": {
|
"requires": {
|
||||||
"device": [ "device:geolocation_control" ],
|
"device": [ "device:geolocation_control" ],
|
||||||
"proxy_resolver": [ "factory" ]
|
"proxy_resolver": [ "factory" ],
|
||||||
|
"chrome_printing": [ "converter" ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -521,3 +521,11 @@ patches:
|
||||||
remained in chromium from a long time ago (last update of that part of the
|
remained in chromium from a long time ago (last update of that part of the
|
||||||
code was around 2012-2013, and this is purely UI, I don't think they have
|
code was around 2012-2013, and this is purely UI, I don't think they have
|
||||||
automated tests for it).
|
automated tests for it).
|
||||||
|
-
|
||||||
|
author: Heilig Benedek <benecene@gmail.com>
|
||||||
|
file: printing.patch
|
||||||
|
description: |
|
||||||
|
Add changeset that was previously applied to sources in chromium_src. The
|
||||||
|
majority of changes originally come from these PRs:
|
||||||
|
* https://github.com/electron/electron/pull/1835
|
||||||
|
* https://github.com/electron/electron/pull/8596
|
||||||
|
|
989
patches/common/chromium/printing.patch
Normal file
989
patches/common/chromium/printing.patch
Normal file
|
@ -0,0 +1,989 @@
|
||||||
|
diff --git a/chrome/browser/printing/print_job_worker.cc b/chrome/browser/printing/print_job_worker.cc
|
||||||
|
index 1065e808e621..13715870097b 100644
|
||||||
|
--- a/chrome/browser/printing/print_job_worker.cc
|
||||||
|
+++ b/chrome/browser/printing/print_job_worker.cc
|
||||||
|
@@ -20,12 +20,13 @@
|
||||||
|
#include "chrome/browser/browser_process.h"
|
||||||
|
#include "chrome/browser/chrome_notification_types.h"
|
||||||
|
#include "chrome/browser/printing/print_job.h"
|
||||||
|
-#include "chrome/grit/generated_resources.h"
|
||||||
|
+#include "electron/grit/electron_resources.h"
|
||||||
|
#include "content/public/browser/browser_thread.h"
|
||||||
|
#include "content/public/browser/notification_service.h"
|
||||||
|
#include "content/public/browser/render_frame_host.h"
|
||||||
|
#include "content/public/browser/web_contents.h"
|
||||||
|
#include "printing/print_job_constants.h"
|
||||||
|
+#include "printing/print_settings_conversion.h"
|
||||||
|
#include "printing/printed_document.h"
|
||||||
|
#include "printing/printing_utils.h"
|
||||||
|
#include "ui/base/l10n/l10n_util.h"
|
||||||
|
@@ -174,7 +175,8 @@ void PrintJobWorker::GetSettings(bool ask_user_for_settings,
|
||||||
|
bool has_selection,
|
||||||
|
MarginType margin_type,
|
||||||
|
bool is_scripted,
|
||||||
|
- bool is_modifiable) {
|
||||||
|
+ bool is_modifiable,
|
||||||
|
+ const base::string16& device_name) {
|
||||||
|
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
||||||
|
DCHECK_EQ(page_number_, PageNumber::npos());
|
||||||
|
|
||||||
|
@@ -200,6 +202,12 @@ void PrintJobWorker::GetSettings(bool ask_user_for_settings,
|
||||||
|
base::BindOnce(&PrintJobWorker::GetSettingsWithUI,
|
||||||
|
base::Unretained(this), document_page_count,
|
||||||
|
has_selection, is_scripted)));
|
||||||
|
+ } else if (!device_name.empty()) {
|
||||||
|
+ BrowserThread::PostTask(
|
||||||
|
+ BrowserThread::UI, FROM_HERE,
|
||||||
|
+ base::BindOnce(&WorkerHoldRefCallback, base::WrapRefCounted(query_),
|
||||||
|
+ base::BindOnce(&PrintJobWorker::InitWithDeviceName,
|
||||||
|
+ base::Unretained(this), device_name)));
|
||||||
|
} else {
|
||||||
|
BrowserThread::PostTask(
|
||||||
|
BrowserThread::UI, FROM_HERE,
|
||||||
|
@@ -316,6 +324,14 @@ void PrintJobWorker::UseDefaultSettings() {
|
||||||
|
GetSettingsDone(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void PrintJobWorker::InitWithDeviceName(const base::string16& device_name) {
|
||||||
|
+ const auto& settings = printing_context_->settings();
|
||||||
|
+ std::unique_ptr<base::DictionaryValue> dic(new base::DictionaryValue);
|
||||||
|
+ printing::PrintSettingsToJobSettings(settings, dic.get());
|
||||||
|
+ dic->SetString(kSettingDeviceName, device_name);
|
||||||
|
+ UpdatePrintSettings(std::move(dic));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void PrintJobWorker::StartPrinting(PrintedDocument* new_document) {
|
||||||
|
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
||||||
|
|
||||||
|
diff --git a/chrome/browser/printing/print_job_worker.h b/chrome/browser/printing/print_job_worker.h
|
||||||
|
index 182f7563e0c7..eed2230627d6 100644
|
||||||
|
--- a/chrome/browser/printing/print_job_worker.h
|
||||||
|
+++ b/chrome/browser/printing/print_job_worker.h
|
||||||
|
@@ -54,7 +54,8 @@ class PrintJobWorker {
|
||||||
|
bool has_selection,
|
||||||
|
MarginType margin_type,
|
||||||
|
bool is_scripted,
|
||||||
|
- bool is_modifiable);
|
||||||
|
+ bool is_modifiable,
|
||||||
|
+ const base::string16& device_name);
|
||||||
|
|
||||||
|
// Set the new print settings from a dictionary value.
|
||||||
|
void SetSettings(std::unique_ptr<base::DictionaryValue> new_settings);
|
||||||
|
@@ -155,6 +156,9 @@ class PrintJobWorker {
|
||||||
|
// systems.
|
||||||
|
void UseDefaultSettings();
|
||||||
|
|
||||||
|
+ // set the printer name
|
||||||
|
+ void InitWithDeviceName(const base::string16& device_name);
|
||||||
|
+
|
||||||
|
// Printing context delegate.
|
||||||
|
const std::unique_ptr<PrintingContext::Delegate> printing_context_delegate_;
|
||||||
|
|
||||||
|
diff --git a/chrome/browser/printing/print_preview_message_handler.cc b/chrome/browser/printing/print_preview_message_handler.cc
|
||||||
|
index e1613a9b52ad..db62078f2c08 100644
|
||||||
|
--- a/chrome/browser/printing/print_preview_message_handler.cc
|
||||||
|
+++ b/chrome/browser/printing/print_preview_message_handler.cc
|
||||||
|
@@ -57,7 +57,7 @@ void StopWorker(int document_cookie) {
|
||||||
|
base::BindOnce(&PrinterQuery::StopWorker, printer_query));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-
|
||||||
|
+#if 0
|
||||||
|
scoped_refptr<base::RefCountedMemory> GetDataFromHandle(
|
||||||
|
base::SharedMemoryHandle handle,
|
||||||
|
uint32_t data_size) {
|
||||||
|
@@ -70,6 +70,7 @@ scoped_refptr<base::RefCountedMemory> GetDataFromHandle(
|
||||||
|
return base::MakeRefCounted<base::RefCountedSharedMemory>(
|
||||||
|
std::move(shared_buf), data_size);
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
@@ -81,7 +82,7 @@ PrintPreviewMessageHandler::PrintPreviewMessageHandler(
|
||||||
|
|
||||||
|
PrintPreviewMessageHandler::~PrintPreviewMessageHandler() {
|
||||||
|
}
|
||||||
|
-
|
||||||
|
+#if 0
|
||||||
|
WebContents* PrintPreviewMessageHandler::GetPrintPreviewDialog() {
|
||||||
|
PrintPreviewDialogController* dialog_controller =
|
||||||
|
PrintPreviewDialogController::GetInstance();
|
||||||
|
@@ -159,6 +160,7 @@ void PrintPreviewMessageHandler::OnDidPreviewPage(
|
||||||
|
GetDataFromHandle(content.metafile_data_handle, content.data_size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
void PrintPreviewMessageHandler::OnMetafileReadyForPrinting(
|
||||||
|
content::RenderFrameHost* render_frame_host,
|
||||||
|
@@ -171,7 +173,8 @@ void PrintPreviewMessageHandler::OnMetafileReadyForPrinting(
|
||||||
|
NOTREACHED();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
+}
|
||||||
|
+#if 0
|
||||||
|
PrintPreviewUI* print_preview_ui = GetPrintPreviewUI(ids.ui_id);
|
||||||
|
if (!print_preview_ui)
|
||||||
|
return;
|
||||||
|
@@ -193,12 +196,13 @@ void PrintPreviewMessageHandler::OnMetafileReadyForPrinting(
|
||||||
|
GetDataFromHandle(content.metafile_data_handle, content.data_size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-
|
||||||
|
+#endif
|
||||||
|
void PrintPreviewMessageHandler::OnPrintPreviewFailed(
|
||||||
|
int document_cookie,
|
||||||
|
const PrintHostMsg_PreviewIds& ids) {
|
||||||
|
StopWorker(document_cookie);
|
||||||
|
-
|
||||||
|
+}
|
||||||
|
+#if 0
|
||||||
|
PrintPreviewUI* print_preview_ui = GetPrintPreviewUI(ids.ui_id);
|
||||||
|
if (!print_preview_ui)
|
||||||
|
return;
|
||||||
|
@@ -318,15 +322,19 @@ void PrintPreviewMessageHandler::OnCompositePdfDocumentDone(
|
||||||
|
base::RefCountedSharedMemoryMapping::CreateFromWholeRegion(region));
|
||||||
|
}
|
||||||
|
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
bool PrintPreviewMessageHandler::OnMessageReceived(
|
||||||
|
const IPC::Message& message,
|
||||||
|
content::RenderFrameHost* render_frame_host) {
|
||||||
|
bool handled = true;
|
||||||
|
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(PrintPreviewMessageHandler, message,
|
||||||
|
render_frame_host)
|
||||||
|
+#if 0
|
||||||
|
IPC_MESSAGE_HANDLER(PrintHostMsg_RequestPrintPreview,
|
||||||
|
OnRequestPrintPreview)
|
||||||
|
IPC_MESSAGE_HANDLER(PrintHostMsg_DidPreviewPage, OnDidPreviewPage)
|
||||||
|
+#endif
|
||||||
|
IPC_MESSAGE_HANDLER(PrintHostMsg_MetafileReadyForPrinting,
|
||||||
|
OnMetafileReadyForPrinting)
|
||||||
|
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||||
|
@@ -336,10 +344,13 @@ bool PrintPreviewMessageHandler::OnMessageReceived(
|
||||||
|
|
||||||
|
handled = true;
|
||||||
|
IPC_BEGIN_MESSAGE_MAP(PrintPreviewMessageHandler, message)
|
||||||
|
+#if 0
|
||||||
|
IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPreviewPageCount,
|
||||||
|
OnDidGetPreviewPageCount)
|
||||||
|
+#endif
|
||||||
|
IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewFailed,
|
||||||
|
OnPrintPreviewFailed)
|
||||||
|
+#if 0
|
||||||
|
IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetDefaultPageLayout,
|
||||||
|
OnDidGetDefaultPageLayout)
|
||||||
|
IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewCancelled,
|
||||||
|
@@ -348,6 +359,7 @@ bool PrintPreviewMessageHandler::OnMessageReceived(
|
||||||
|
OnInvalidPrinterSettings)
|
||||||
|
IPC_MESSAGE_HANDLER(PrintHostMsg_SetOptionsFromDocument,
|
||||||
|
OnSetOptionsFromDocument)
|
||||||
|
+#endif
|
||||||
|
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||||
|
IPC_END_MESSAGE_MAP()
|
||||||
|
return handled;
|
||||||
|
diff --git a/chrome/browser/printing/print_preview_message_handler.h b/chrome/browser/printing/print_preview_message_handler.h
|
||||||
|
index 6356792f29e8..5592de3c097f 100644
|
||||||
|
--- a/chrome/browser/printing/print_preview_message_handler.h
|
||||||
|
+++ b/chrome/browser/printing/print_preview_message_handler.h
|
||||||
|
@@ -37,8 +37,7 @@ struct PageSizeMargins;
|
||||||
|
|
||||||
|
// Manages the print preview handling for a WebContents.
|
||||||
|
class PrintPreviewMessageHandler
|
||||||
|
- : public content::WebContentsObserver,
|
||||||
|
- public content::WebContentsUserData<PrintPreviewMessageHandler> {
|
||||||
|
+ : public content::WebContentsObserver {
|
||||||
|
public:
|
||||||
|
~PrintPreviewMessageHandler() override;
|
||||||
|
|
||||||
|
@@ -46,10 +45,11 @@ class PrintPreviewMessageHandler
|
||||||
|
bool OnMessageReceived(const IPC::Message& message,
|
||||||
|
content::RenderFrameHost* render_frame_host) override;
|
||||||
|
|
||||||
|
- private:
|
||||||
|
+ protected:
|
||||||
|
explicit PrintPreviewMessageHandler(content::WebContents* web_contents);
|
||||||
|
friend class content::WebContentsUserData<PrintPreviewMessageHandler>;
|
||||||
|
|
||||||
|
+#if 0
|
||||||
|
// Gets the print preview dialog associated with the WebContents being
|
||||||
|
// observed.
|
||||||
|
content::WebContents* GetPrintPreviewDialog();
|
||||||
|
@@ -72,12 +72,14 @@ class PrintPreviewMessageHandler
|
||||||
|
void OnDidPreviewPage(content::RenderFrameHost* render_frame_host,
|
||||||
|
const PrintHostMsg_DidPreviewPage_Params& params,
|
||||||
|
const PrintHostMsg_PreviewIds& ids);
|
||||||
|
- void OnMetafileReadyForPrinting(
|
||||||
|
+#endif
|
||||||
|
+ virtual void OnMetafileReadyForPrinting(
|
||||||
|
content::RenderFrameHost* render_frame_host,
|
||||||
|
const PrintHostMsg_DidPreviewDocument_Params& params,
|
||||||
|
const PrintHostMsg_PreviewIds& ids);
|
||||||
|
- void OnPrintPreviewFailed(int document_cookie,
|
||||||
|
- const PrintHostMsg_PreviewIds& ids);
|
||||||
|
+ virtual void OnPrintPreviewFailed(int document_cookie,
|
||||||
|
+ const PrintHostMsg_PreviewIds& ids);
|
||||||
|
+#if 0
|
||||||
|
void OnPrintPreviewCancelled(int document_cookie,
|
||||||
|
const PrintHostMsg_PreviewIds& ids);
|
||||||
|
void OnInvalidPrinterSettings(int document_cookie,
|
||||||
|
@@ -104,6 +106,7 @@ class PrintPreviewMessageHandler
|
||||||
|
const PrintHostMsg_PreviewIds& ids,
|
||||||
|
mojom::PdfCompositor::Status status,
|
||||||
|
base::ReadOnlySharedMemoryRegion region);
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
base::WeakPtrFactory<PrintPreviewMessageHandler> weak_ptr_factory_;
|
||||||
|
|
||||||
|
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
|
||||||
|
index 9b0c15b3c501..388994072186 100644
|
||||||
|
--- a/chrome/browser/printing/print_view_manager_base.cc
|
||||||
|
+++ b/chrome/browser/printing/print_view_manager_base.cc
|
||||||
|
@@ -30,7 +30,7 @@
|
||||||
|
#include "chrome/browser/ui/simple_message_box.h"
|
||||||
|
#include "chrome/browser/ui/webui/print_preview/printer_handler.h"
|
||||||
|
#include "chrome/common/pref_names.h"
|
||||||
|
-#include "chrome/grit/generated_resources.h"
|
||||||
|
+#include "electron/grit/electron_resources.h"
|
||||||
|
#include "components/prefs/pref_service.h"
|
||||||
|
#include "components/printing/browser/print_composite_client.h"
|
||||||
|
#include "components/printing/browser/print_manager_utils.h"
|
||||||
|
@@ -67,6 +67,8 @@ using PrintSettingsCallback =
|
||||||
|
base::OnceCallback<void(scoped_refptr<PrinterQuery>)>;
|
||||||
|
|
||||||
|
void ShowWarningMessageBox(const base::string16& message) {
|
||||||
|
+ LOG(ERROR) << "Invalid printer settings " << message;
|
||||||
|
+#if 0
|
||||||
|
// Runs always on the UI thread.
|
||||||
|
static bool is_dialog_shown = false;
|
||||||
|
if (is_dialog_shown)
|
||||||
|
@@ -75,6 +77,7 @@ void ShowWarningMessageBox(const base::string16& message) {
|
||||||
|
base::AutoReset<bool> auto_reset(&is_dialog_shown, true);
|
||||||
|
|
||||||
|
chrome::ShowWarningMessageBox(nullptr, base::string16(), message);
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||||
|
@@ -112,12 +115,14 @@ PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents)
|
||||||
|
queue_(g_browser_process->print_job_manager()->queue()),
|
||||||
|
weak_ptr_factory_(this) {
|
||||||
|
DCHECK(queue_);
|
||||||
|
+#if 0
|
||||||
|
Profile* profile =
|
||||||
|
Profile::FromBrowserContext(web_contents->GetBrowserContext());
|
||||||
|
printing_enabled_.Init(
|
||||||
|
prefs::kPrintingEnabled, profile->GetPrefs(),
|
||||||
|
base::Bind(&PrintViewManagerBase::UpdatePrintingEnabled,
|
||||||
|
weak_ptr_factory_.GetWeakPtr()));
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintViewManagerBase::~PrintViewManagerBase() {
|
||||||
|
@@ -125,12 +130,16 @@ PrintViewManagerBase::~PrintViewManagerBase() {
|
||||||
|
DisconnectFromCurrentPrintJob();
|
||||||
|
}
|
||||||
|
|
||||||
|
-bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh) {
|
||||||
|
+bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh,
|
||||||
|
+ bool silent,
|
||||||
|
+ bool print_background,
|
||||||
|
+ const base::string16& device_name) {
|
||||||
|
DisconnectFromCurrentPrintJob();
|
||||||
|
|
||||||
|
SetPrintingRFH(rfh);
|
||||||
|
int32_t id = rfh->GetRoutingID();
|
||||||
|
- return PrintNowInternal(rfh, std::make_unique<PrintMsg_PrintPages>(id));
|
||||||
|
+ return PrintNowInternal(rfh, std::make_unique<PrintMsg_PrintPages>(
|
||||||
|
+ id, silent, print_background, device_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||||
|
@@ -249,7 +258,7 @@ void PrintViewManagerBase::UpdatePrintingEnabled() {
|
||||||
|
// The Unretained() is safe because ForEachFrame() is synchronous.
|
||||||
|
web_contents()->ForEachFrame(base::BindRepeating(
|
||||||
|
&PrintViewManagerBase::SendPrintingEnabled, base::Unretained(this),
|
||||||
|
- printing_enabled_.GetValue()));
|
||||||
|
+ true));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintViewManagerBase::NavigationStopped() {
|
||||||
|
@@ -341,8 +350,10 @@ void PrintViewManagerBase::OnDidPrintDocument(
|
||||||
|
void PrintViewManagerBase::OnPrintingFailed(int cookie) {
|
||||||
|
PrintManager::OnPrintingFailed(cookie);
|
||||||
|
|
||||||
|
+#if 0
|
||||||
|
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||||
|
ShowPrintErrorDialog();
|
||||||
|
+#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ReleasePrinterQuery();
|
||||||
|
@@ -592,6 +603,10 @@ void PrintViewManagerBase::ReleasePrintJob() {
|
||||||
|
content::RenderFrameHost* rfh = printing_rfh_;
|
||||||
|
printing_rfh_ = nullptr;
|
||||||
|
|
||||||
|
+ if (!callback.is_null()) {
|
||||||
|
+ callback.Run(printing_succeeded_ && print_job_);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!print_job_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
diff --git a/chrome/browser/printing/print_view_manager_base.h b/chrome/browser/printing/print_view_manager_base.h
|
||||||
|
index fe0e0b5b065c..6670fc8abd2d 100644
|
||||||
|
--- a/chrome/browser/printing/print_view_manager_base.h
|
||||||
|
+++ b/chrome/browser/printing/print_view_manager_base.h
|
||||||
|
@@ -7,6 +7,7 @@
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
+#include "base/callback.h"
|
||||||
|
#include "base/macros.h"
|
||||||
|
#include "base/memory/read_only_shared_memory_region.h"
|
||||||
|
#include "base/memory/scoped_refptr.h"
|
||||||
|
@@ -47,7 +48,10 @@ 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(content::RenderFrameHost* rfh);
|
||||||
|
+ virtual bool PrintNow(content::RenderFrameHost* rfh,
|
||||||
|
+ bool silent,
|
||||||
|
+ bool print_background,
|
||||||
|
+ const base::string16& device_name);
|
||||||
|
|
||||||
|
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||||
|
// Prints the document in |print_data| with settings specified in
|
||||||
|
@@ -72,6 +76,8 @@ class PrintViewManagerBase : public content::NotificationObserver,
|
||||||
|
|
||||||
|
base::string16 RenderSourceName();
|
||||||
|
|
||||||
|
+ void SetCallback(const base::Callback<void(bool)>& cb) { callback = cb; };
|
||||||
|
+
|
||||||
|
protected:
|
||||||
|
explicit PrintViewManagerBase(content::WebContents* web_contents);
|
||||||
|
|
||||||
|
@@ -208,6 +214,8 @@ class PrintViewManagerBase : public content::NotificationObserver,
|
||||||
|
|
||||||
|
scoped_refptr<PrintQueriesQueue> queue_;
|
||||||
|
|
||||||
|
+ base::Callback<void(bool)> callback;
|
||||||
|
+
|
||||||
|
base::WeakPtrFactory<PrintViewManagerBase> weak_ptr_factory_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(PrintViewManagerBase);
|
||||||
|
diff --git a/chrome/browser/printing/print_view_manager_common.cc b/chrome/browser/printing/print_view_manager_common.cc
|
||||||
|
index 3d36b0b972b6..3400f4a3470b 100644
|
||||||
|
--- a/chrome/browser/printing/print_view_manager_common.cc
|
||||||
|
+++ b/chrome/browser/printing/print_view_manager_common.cc
|
||||||
|
@@ -11,12 +11,12 @@
|
||||||
|
#include "printing/buildflags/buildflags.h"
|
||||||
|
#include "url/gurl.h"
|
||||||
|
|
||||||
|
-#if BUILDFLAG(ENABLE_EXTENSIONS)
|
||||||
|
+#if 0
|
||||||
|
#include "components/guest_view/browser/guest_view_manager.h"
|
||||||
|
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
|
||||||
|
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
|
||||||
|
|
||||||
|
-#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||||
|
+#if 0
|
||||||
|
#include "chrome/browser/printing/print_view_manager.h"
|
||||||
|
#else
|
||||||
|
#include "chrome/browser/printing/print_view_manager_basic.h"
|
||||||
|
@@ -25,7 +25,7 @@
|
||||||
|
namespace printing {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
-#if BUILDFLAG(ENABLE_EXTENSIONS)
|
||||||
|
+#if 0
|
||||||
|
// Stores |guest_contents| in |result| and returns true if |guest_contents| is a
|
||||||
|
// full page MimeHandlerViewGuest plugin. Otherwise, returns false.
|
||||||
|
bool StoreFullPagePlugin(content::WebContents** result,
|
||||||
|
@@ -43,7 +43,7 @@ bool StoreFullPagePlugin(content::WebContents** result,
|
||||||
|
// If we have a single full-page embedded mime handler view guest, print the
|
||||||
|
// guest's WebContents instead.
|
||||||
|
content::WebContents* GetWebContentsToUse(content::WebContents* contents) {
|
||||||
|
-#if BUILDFLAG(ENABLE_EXTENSIONS)
|
||||||
|
+#if 0
|
||||||
|
guest_view::GuestViewManager* guest_view_manager =
|
||||||
|
guest_view::GuestViewManager::FromBrowserContext(
|
||||||
|
contents->GetBrowserContext());
|
||||||
|
@@ -69,7 +69,8 @@ content::RenderFrameHost* GetRenderFrameHostToUse(
|
||||||
|
void StartPrint(content::WebContents* contents,
|
||||||
|
bool print_preview_disabled,
|
||||||
|
bool has_selection) {
|
||||||
|
-#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||||
|
+
|
||||||
|
+#if 0
|
||||||
|
using PrintViewManagerImpl = PrintViewManager;
|
||||||
|
#else
|
||||||
|
using PrintViewManagerImpl = PrintViewManagerBasic;
|
||||||
|
@@ -85,18 +86,20 @@ void StartPrint(content::WebContents* contents,
|
||||||
|
GetRenderFrameHostToUse(contents, contents_to_use);
|
||||||
|
if (!rfh_to_use)
|
||||||
|
return;
|
||||||
|
-
|
||||||
|
+#if 0
|
||||||
|
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||||
|
if (!print_preview_disabled) {
|
||||||
|
print_view_manager->PrintPreviewNow(rfh_to_use, has_selection);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif // ENABLE_PRINT_PREVIEW
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
- print_view_manager->PrintNow(rfh_to_use);
|
||||||
|
+ print_view_manager->PrintNow(rfh_to_use, false, true, base::string16());
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartBasicPrint(content::WebContents* contents) {
|
||||||
|
+#if 0
|
||||||
|
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||||
|
content::WebContents* contents_to_use = GetWebContentsToUse(contents);
|
||||||
|
PrintViewManager* print_view_manager =
|
||||||
|
@@ -111,6 +114,7 @@ void StartBasicPrint(content::WebContents* contents) {
|
||||||
|
|
||||||
|
print_view_manager->BasicPrint(rfh_to_use);
|
||||||
|
#endif // ENABLE_PRINT_PREVIEW
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
content::RenderFrameHost* GetFrameToPrint(content::WebContents* contents) {
|
||||||
|
diff --git a/chrome/browser/printing/printer_query.cc b/chrome/browser/printing/printer_query.cc
|
||||||
|
index cc2368731367..159ec3a04502 100644
|
||||||
|
--- a/chrome/browser/printing/printer_query.cc
|
||||||
|
+++ b/chrome/browser/printing/printer_query.cc
|
||||||
|
@@ -94,7 +94,31 @@ void PrinterQuery::GetSettings(GetSettingsAskParam ask_user_for_settings,
|
||||||
|
base::BindOnce(&PrintJobWorker::GetSettings,
|
||||||
|
base::Unretained(worker_.get()),
|
||||||
|
is_print_dialog_box_shown_, expected_page_count,
|
||||||
|
- has_selection, margin_type, is_scripted, is_modifiable));
|
||||||
|
+ has_selection, margin_type, is_scripted, is_modifiable,
|
||||||
|
+ base::string16()));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+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::string16& device_name,
|
||||||
|
+ base::OnceClosure callback) {
|
||||||
|
+ DCHECK(RunsTasksInCurrentSequence());
|
||||||
|
+ DCHECK(!is_print_dialog_box_shown_);
|
||||||
|
+
|
||||||
|
+ StartWorker(std::move(callback));
|
||||||
|
+
|
||||||
|
+ is_print_dialog_box_shown_ = false;
|
||||||
|
+ worker_->PostTask(
|
||||||
|
+ FROM_HERE,
|
||||||
|
+ base::BindOnce(&PrintJobWorker::GetSettings,
|
||||||
|
+ base::Unretained(worker_.get()),
|
||||||
|
+ is_print_dialog_box_shown_, expected_page_count,
|
||||||
|
+ has_selection, margin_type, is_scripted, is_modifiable,
|
||||||
|
+ device_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrinterQuery::SetSettings(
|
||||||
|
diff --git a/chrome/browser/printing/printer_query.h b/chrome/browser/printing/printer_query.h
|
||||||
|
index 64db84f9f853..0e12adfe7957 100644
|
||||||
|
--- a/chrome/browser/printing/printer_query.h
|
||||||
|
+++ b/chrome/browser/printing/printer_query.h
|
||||||
|
@@ -59,6 +59,15 @@ class PrinterQuery : public base::RefCountedThreadSafe<PrinterQuery> {
|
||||||
|
bool is_modifiable,
|
||||||
|
base::OnceClosure 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::string16& device_name,
|
||||||
|
+ base::OnceClosure callback);
|
||||||
|
+
|
||||||
|
// Updates the current settings with |new_settings| dictionary values.
|
||||||
|
virtual void SetSettings(std::unique_ptr<base::DictionaryValue> new_settings,
|
||||||
|
base::OnceClosure callback);
|
||||||
|
diff --git a/chrome/browser/printing/printing_message_filter.cc b/chrome/browser/printing/printing_message_filter.cc
|
||||||
|
index 54866fdcdb64..40d6bd62706c 100644
|
||||||
|
--- a/chrome/browser/printing/printing_message_filter.cc
|
||||||
|
+++ b/chrome/browser/printing/printing_message_filter.cc
|
||||||
|
@@ -94,12 +94,12 @@ PrintViewManager* GetPrintViewManager(int render_process_id,
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
-PrintingMessageFilter::PrintingMessageFilter(int render_process_id,
|
||||||
|
- Profile* profile)
|
||||||
|
+PrintingMessageFilter::PrintingMessageFilter(int render_process_id)
|
||||||
|
: BrowserMessageFilter(PrintMsgStart),
|
||||||
|
render_process_id_(render_process_id),
|
||||||
|
queue_(g_browser_process->print_job_manager()->queue()) {
|
||||||
|
DCHECK(queue_.get());
|
||||||
|
+#if 0
|
||||||
|
printing_shutdown_notifier_ =
|
||||||
|
PrintingMessageFilterShutdownNotifierFactory::GetInstance()
|
||||||
|
->Get(profile)
|
||||||
|
@@ -108,6 +108,7 @@ PrintingMessageFilter::PrintingMessageFilter(int render_process_id,
|
||||||
|
is_printing_enabled_.Init(prefs::kPrintingEnabled, profile->GetPrefs());
|
||||||
|
is_printing_enabled_.MoveToThread(
|
||||||
|
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintingMessageFilter::~PrintingMessageFilter() {
|
||||||
|
@@ -116,7 +117,9 @@ PrintingMessageFilter::~PrintingMessageFilter() {
|
||||||
|
|
||||||
|
void PrintingMessageFilter::ShutdownOnUIThread() {
|
||||||
|
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||||
|
+#if 0
|
||||||
|
is_printing_enabled_.Destroy();
|
||||||
|
+#endif
|
||||||
|
printing_shutdown_notifier_.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -145,6 +148,8 @@ bool PrintingMessageFilter::OnMessageReceived(const IPC::Message& message) {
|
||||||
|
#endif
|
||||||
|
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_GetDefaultPrintSettings,
|
||||||
|
OnGetDefaultPrintSettings)
|
||||||
|
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_InitSettingWithDeviceName,
|
||||||
|
+ OnInitSettingWithDeviceName)
|
||||||
|
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_ScriptedPrint, OnScriptedPrint)
|
||||||
|
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_UpdatePrintSettings,
|
||||||
|
OnUpdatePrintSettings)
|
||||||
|
@@ -188,7 +193,7 @@ void PrintingMessageFilter::OnTempFileForPrintingWritten(int render_frame_id,
|
||||||
|
void PrintingMessageFilter::OnGetDefaultPrintSettings(IPC::Message* reply_msg) {
|
||||||
|
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||||
|
scoped_refptr<PrinterQuery> printer_query;
|
||||||
|
- if (!is_printing_enabled_.GetValue()) {
|
||||||
|
+ if (false) {
|
||||||
|
// Reply with NULL query.
|
||||||
|
OnGetDefaultPrintSettingsReply(printer_query, reply_msg);
|
||||||
|
return;
|
||||||
|
@@ -208,6 +213,26 @@ void PrintingMessageFilter::OnGetDefaultPrintSettings(IPC::Message* reply_msg) {
|
||||||
|
printer_query, reply_msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
+void PrintingMessageFilter::OnInitSettingWithDeviceName(
|
||||||
|
+ const base::string16& device_name,
|
||||||
|
+ IPC::Message* reply_msg) {
|
||||||
|
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||||
|
+ scoped_refptr<PrinterQuery> printer_query;
|
||||||
|
+ printer_query = queue_->PopPrinterQuery(0);
|
||||||
|
+ if (!printer_query.get()) {
|
||||||
|
+ printer_query =
|
||||||
|
+ queue_->CreatePrinterQuery(render_process_id_, reply_msg->routing_id());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Loads default settings. This is asynchronous, only the IPC message sender
|
||||||
|
+ // will hang until the settings are retrieved.
|
||||||
|
+ printer_query->GetSettings(
|
||||||
|
+ PrinterQuery::GetSettingsAskParam::DEFAULTS, 0, false, DEFAULT_MARGINS,
|
||||||
|
+ true, true, device_name,
|
||||||
|
+ base::Bind(&PrintingMessageFilter::OnGetDefaultPrintSettingsReply, this,
|
||||||
|
+ printer_query, reply_msg));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void PrintingMessageFilter::OnGetDefaultPrintSettingsReply(
|
||||||
|
scoped_refptr<PrinterQuery> printer_query,
|
||||||
|
IPC::Message* reply_msg) {
|
||||||
|
@@ -301,7 +326,7 @@ void PrintingMessageFilter::OnUpdatePrintSettings(
|
||||||
|
std::unique_ptr<base::DictionaryValue> new_settings(job_settings.DeepCopy());
|
||||||
|
|
||||||
|
scoped_refptr<PrinterQuery> printer_query;
|
||||||
|
- if (!is_printing_enabled_.GetValue()) {
|
||||||
|
+ if (false) {
|
||||||
|
// Reply with NULL query.
|
||||||
|
OnUpdatePrintSettingsReply(printer_query, reply_msg);
|
||||||
|
return;
|
||||||
|
@@ -361,10 +386,13 @@ void PrintingMessageFilter::OnUpdatePrintSettingsReply(
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+
|
||||||
|
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||||
|
void PrintingMessageFilter::OnCheckForCancel(const PrintHostMsg_PreviewIds& ids,
|
||||||
|
bool* cancel) {
|
||||||
|
+#if 0
|
||||||
|
PrintPreviewUI::GetCurrentPrintPreviewStatus(ids, cancel);
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
diff --git a/chrome/browser/printing/printing_message_filter.h b/chrome/browser/printing/printing_message_filter.h
|
||||||
|
index a881a853bfb0..46ebeede1955 100644
|
||||||
|
--- a/chrome/browser/printing/printing_message_filter.h
|
||||||
|
+++ b/chrome/browser/printing/printing_message_filter.h
|
||||||
|
@@ -38,7 +38,7 @@ class PrinterQuery;
|
||||||
|
// renderer process on the IPC thread.
|
||||||
|
class PrintingMessageFilter : public content::BrowserMessageFilter {
|
||||||
|
public:
|
||||||
|
- PrintingMessageFilter(int render_process_id, Profile* profile);
|
||||||
|
+ PrintingMessageFilter(int render_process_id);
|
||||||
|
|
||||||
|
// content::BrowserMessageFilter methods.
|
||||||
|
void OverrideThreadForMessage(const IPC::Message& message,
|
||||||
|
@@ -73,6 +73,11 @@ class PrintingMessageFilter : public content::BrowserMessageFilter {
|
||||||
|
|
||||||
|
// Get the default print setting.
|
||||||
|
void OnGetDefaultPrintSettings(IPC::Message* reply_msg);
|
||||||
|
+
|
||||||
|
+ // Set deviceName
|
||||||
|
+ void OnInitSettingWithDeviceName(const base::string16& device_name,
|
||||||
|
+ IPC::Message* reply_msg);
|
||||||
|
+
|
||||||
|
void OnGetDefaultPrintSettingsReply(scoped_refptr<PrinterQuery> printer_query,
|
||||||
|
IPC::Message* reply_msg);
|
||||||
|
|
||||||
|
diff --git a/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc b/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc
|
||||||
|
index 38fd116aa096..62fcfaa00084 100644
|
||||||
|
--- a/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc
|
||||||
|
+++ b/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc
|
||||||
|
@@ -19,7 +19,7 @@
|
||||||
|
#include "third_party/blink/public/web/web_element.h"
|
||||||
|
#include "third_party/blink/public/web/web_local_frame.h"
|
||||||
|
|
||||||
|
-#if BUILDFLAG(ENABLE_EXTENSIONS)
|
||||||
|
+#if 0
|
||||||
|
#include "chrome/common/extensions/extension_constants.h"
|
||||||
|
#include "extensions/common/constants.h"
|
||||||
|
#include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.h"
|
||||||
|
@@ -45,7 +45,7 @@ bool ChromePrintRenderFrameHelperDelegate::CancelPrerender(
|
||||||
|
// Return the PDF object element if |frame| is the out of process PDF extension.
|
||||||
|
blink::WebElement ChromePrintRenderFrameHelperDelegate::GetPdfElement(
|
||||||
|
blink::WebLocalFrame* frame) {
|
||||||
|
-#if BUILDFLAG(ENABLE_EXTENSIONS)
|
||||||
|
+#if 0
|
||||||
|
GURL url = frame->GetDocument().Url();
|
||||||
|
bool inside_print_preview = url.GetOrigin() == chrome::kChromeUIPrintURL;
|
||||||
|
bool inside_pdf_extension =
|
||||||
|
@@ -71,7 +71,7 @@ bool ChromePrintRenderFrameHelperDelegate::IsPrintPreviewEnabled() {
|
||||||
|
|
||||||
|
bool ChromePrintRenderFrameHelperDelegate::OverridePrint(
|
||||||
|
blink::WebLocalFrame* frame) {
|
||||||
|
-#if BUILDFLAG(ENABLE_EXTENSIONS)
|
||||||
|
+#if 0
|
||||||
|
if (!frame->GetDocument().IsPluginDocument())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
diff --git a/components/printing/common/print_messages.h b/components/printing/common/print_messages.h
|
||||||
|
index d29bb6aedecd..bb0bd7bfa494 100644
|
||||||
|
--- a/components/printing/common/print_messages.h
|
||||||
|
+++ b/components/printing/common/print_messages.h
|
||||||
|
@@ -367,7 +367,10 @@ IPC_MESSAGE_ROUTED0(PrintMsg_PrintNodeUnderContextMenu)
|
||||||
|
#if BUILDFLAG(ENABLE_PRINTING)
|
||||||
|
// Tells the RenderFrame to switch the CSS to print media type, renders every
|
||||||
|
// requested pages and switch back the CSS to display media type.
|
||||||
|
-IPC_MESSAGE_ROUTED0(PrintMsg_PrintPages)
|
||||||
|
+IPC_MESSAGE_ROUTED3(PrintMsg_PrintPages,
|
||||||
|
+ bool /* silent print */,
|
||||||
|
+ bool /* print page's background */,
|
||||||
|
+ base::string16 /* device name*/)
|
||||||
|
|
||||||
|
// Like PrintMsg_PrintPages, but using the print preview document's frame/node.
|
||||||
|
IPC_MESSAGE_ROUTED0(PrintMsg_PrintForSystemDialog)
|
||||||
|
@@ -425,6 +428,11 @@ IPC_MESSAGE_ROUTED2(PrintHostMsg_DidPrintFrameContent,
|
||||||
|
IPC_SYNC_MESSAGE_ROUTED0_1(PrintHostMsg_GetDefaultPrintSettings,
|
||||||
|
PrintMsg_Print_Params /* default_settings */)
|
||||||
|
|
||||||
|
+// you can set the printer
|
||||||
|
+IPC_SYNC_MESSAGE_ROUTED1_1(PrintHostMsg_InitSettingWithDeviceName,
|
||||||
|
+ base::string16, /* device name */
|
||||||
|
+ PrintMsg_Print_Params /* default_settings */)
|
||||||
|
+
|
||||||
|
// The renderer wants to update the current print settings with new
|
||||||
|
// |job_settings|.
|
||||||
|
IPC_SYNC_MESSAGE_ROUTED2_2(PrintHostMsg_UpdatePrintSettings,
|
||||||
|
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc
|
||||||
|
index c7ea5cf76aa6..1c3177e679ff 100644
|
||||||
|
--- a/components/printing/renderer/print_render_frame_helper.cc
|
||||||
|
+++ b/components/printing/renderer/print_render_frame_helper.cc
|
||||||
|
@@ -1093,7 +1093,9 @@ void PrintRenderFrameHelper::OnDestruct() {
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
-void PrintRenderFrameHelper::OnPrintPages() {
|
||||||
|
+void PrintRenderFrameHelper::OnPrintPages(bool silent,
|
||||||
|
+ bool print_background,
|
||||||
|
+ const base::string16& device_name) {
|
||||||
|
if (ipc_nesting_level_ > 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
@@ -1106,7 +1108,7 @@ void PrintRenderFrameHelper::OnPrintPages() {
|
||||||
|
// If we are printing a PDF extension frame, find the plugin node and print
|
||||||
|
// that instead.
|
||||||
|
auto plugin = delegate_->GetPdfElement(frame);
|
||||||
|
- Print(frame, plugin, false /* is_scripted? */);
|
||||||
|
+ Print(frame, plugin, false, silent, print_background, device_name);
|
||||||
|
if (weak_this)
|
||||||
|
frame->DispatchAfterPrintEvent();
|
||||||
|
// WARNING: |this| may be gone at this point. Do not do any more work here and
|
||||||
|
@@ -1158,6 +1160,8 @@ void PrintRenderFrameHelper::OnPrintPreview(
|
||||||
|
if (ipc_nesting_level_ > 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
+ blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
|
||||||
|
+ print_preview_context_.InitWithFrame(frame);
|
||||||
|
print_preview_context_.OnPrintPreview();
|
||||||
|
|
||||||
|
UMA_HISTOGRAM_ENUMERATION("PrintPreview.PreviewEvent",
|
||||||
|
@@ -1552,7 +1556,10 @@ void PrintRenderFrameHelper::PrintNode(const blink::WebNode& node) {
|
||||||
|
|
||||||
|
void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame,
|
||||||
|
const blink::WebNode& node,
|
||||||
|
- bool is_scripted) {
|
||||||
|
+ bool is_scripted,
|
||||||
|
+ bool silent,
|
||||||
|
+ bool print_background,
|
||||||
|
+ const base::string16& device_name) {
|
||||||
|
// If still not finished with earlier print request simply ignore.
|
||||||
|
if (prep_frame_view_)
|
||||||
|
return;
|
||||||
|
@@ -1560,7 +1567,7 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame,
|
||||||
|
FrameReference frame_ref(frame);
|
||||||
|
|
||||||
|
int expected_page_count = 0;
|
||||||
|
- if (!CalculateNumberOfPages(frame, node, &expected_page_count)) {
|
||||||
|
+ if (!CalculateNumberOfPages(frame, node, &expected_page_count, device_name)) {
|
||||||
|
DidFinishPrinting(FAIL_PRINT_INIT);
|
||||||
|
return; // Failed to init print page settings.
|
||||||
|
}
|
||||||
|
@@ -1580,8 +1587,9 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame,
|
||||||
|
|
||||||
|
PrintMsg_PrintPages_Params print_settings;
|
||||||
|
auto self = weak_ptr_factory_.GetWeakPtr();
|
||||||
|
- GetPrintSettingsFromUser(frame_ref.GetFrame(), node, expected_page_count,
|
||||||
|
- is_scripted, &print_settings);
|
||||||
|
+ if (!silent)
|
||||||
|
+ GetPrintSettingsFromUser(frame_ref.GetFrame(), node, expected_page_count,
|
||||||
|
+ is_scripted, &print_settings);
|
||||||
|
// Check if |this| is still valid.
|
||||||
|
if (!self)
|
||||||
|
return;
|
||||||
|
@@ -1591,6 +1599,7 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame,
|
||||||
|
? blink::kWebPrintScalingOptionSourceSize
|
||||||
|
: scaling_option;
|
||||||
|
SetPrintPagesParams(print_settings);
|
||||||
|
+ print_settings.params.should_print_backgrounds = print_background;
|
||||||
|
if (print_settings.params.dpi.IsEmpty() ||
|
||||||
|
!print_settings.params.document_cookie) {
|
||||||
|
DidFinishPrinting(OK); // Release resources and fail silently on failure.
|
||||||
|
@@ -1600,7 +1609,6 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame,
|
||||||
|
|
||||||
|
// Render Pages for printing.
|
||||||
|
if (!RenderPagesForPrint(frame_ref.GetFrame(), node)) {
|
||||||
|
- LOG(ERROR) << "RenderPagesForPrint failed";
|
||||||
|
DidFinishPrinting(FAIL_PRINT);
|
||||||
|
}
|
||||||
|
scripting_throttler_.Reset();
|
||||||
|
@@ -1778,10 +1786,17 @@ std::vector<int> PrintRenderFrameHelper::GetPrintedPages(
|
||||||
|
return printed_pages;
|
||||||
|
}
|
||||||
|
|
||||||
|
-bool PrintRenderFrameHelper::InitPrintSettings(bool fit_to_paper_size) {
|
||||||
|
+bool PrintRenderFrameHelper::InitPrintSettings(
|
||||||
|
+ bool fit_to_paper_size,
|
||||||
|
+ const base::string16& device_name) {
|
||||||
|
PrintMsg_PrintPages_Params settings;
|
||||||
|
+ if (device_name.empty()) {
|
||||||
|
Send(new PrintHostMsg_GetDefaultPrintSettings(routing_id(),
|
||||||
|
&settings.params));
|
||||||
|
+ } else {
|
||||||
|
+ Send(new PrintHostMsg_InitSettingWithDeviceName(routing_id(), device_name,
|
||||||
|
+ &settings.params));
|
||||||
|
+ }
|
||||||
|
// Check if the printer returned any settings, if the settings is empty, we
|
||||||
|
// can safely assume there are no printer drivers configured. So we safely
|
||||||
|
// terminate.
|
||||||
|
@@ -1803,10 +1818,11 @@ bool PrintRenderFrameHelper::InitPrintSettings(bool fit_to_paper_size) {
|
||||||
|
|
||||||
|
bool PrintRenderFrameHelper::CalculateNumberOfPages(blink::WebLocalFrame* frame,
|
||||||
|
const blink::WebNode& node,
|
||||||
|
- int* number_of_pages) {
|
||||||
|
+ int* number_of_pages,
|
||||||
|
+ const base::string16& device_name) {
|
||||||
|
DCHECK(frame);
|
||||||
|
bool fit_to_paper_size = !(PrintingNodeOrPdfFrame(frame, node));
|
||||||
|
- if (!InitPrintSettings(fit_to_paper_size)) {
|
||||||
|
+ if (!InitPrintSettings(fit_to_paper_size, device_name)) {
|
||||||
|
notify_browser_of_print_failure_ = false;
|
||||||
|
Send(new PrintHostMsg_ShowInvalidPrinterSettingsError(routing_id()));
|
||||||
|
return false;
|
||||||
|
@@ -1885,11 +1901,13 @@ bool PrintRenderFrameHelper::UpdatePrintSettings(
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#if 0
|
||||||
|
if (!job_settings->GetInteger(kPreviewUIID, &settings.params.preview_ui_id)) {
|
||||||
|
NOTREACHED();
|
||||||
|
print_preview_context_.set_error(PREVIEW_ERROR_BAD_SETTING);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
// Validate expected print preview settings.
|
||||||
|
if (!job_settings->GetInteger(kPreviewRequestID,
|
||||||
|
diff --git a/components/printing/renderer/print_render_frame_helper.h b/components/printing/renderer/print_render_frame_helper.h
|
||||||
|
index 6e2d7e1467b7..0e6e8ea770f5 100644
|
||||||
|
--- a/components/printing/renderer/print_render_frame_helper.h
|
||||||
|
+++ b/components/printing/renderer/print_render_frame_helper.h
|
||||||
|
@@ -186,7 +186,9 @@ class PrintRenderFrameHelper
|
||||||
|
bool OnMessageReceived(const IPC::Message& message) override;
|
||||||
|
|
||||||
|
// Message handlers ---------------------------------------------------------
|
||||||
|
- void OnPrintPages();
|
||||||
|
+ void OnPrintPages(bool silent,
|
||||||
|
+ bool print_background,
|
||||||
|
+ const base::string16& device_name);
|
||||||
|
void OnPrintForSystemDialog();
|
||||||
|
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||||
|
void OnInitiatePrintPreview(bool has_selection);
|
||||||
|
@@ -238,7 +240,10 @@ class PrintRenderFrameHelper
|
||||||
|
// WARNING: |this| may be gone after this method returns.
|
||||||
|
void Print(blink::WebLocalFrame* frame,
|
||||||
|
const blink::WebNode& node,
|
||||||
|
- bool is_scripted);
|
||||||
|
+ bool is_scripted,
|
||||||
|
+ bool silent = false,
|
||||||
|
+ bool print_background = false,
|
||||||
|
+ const base::string16& device_name = base::string16());
|
||||||
|
|
||||||
|
// Notification when printing is done - signal tear-down/free resources.
|
||||||
|
void DidFinishPrinting(PrintingResult result);
|
||||||
|
@@ -247,12 +252,15 @@ class PrintRenderFrameHelper
|
||||||
|
|
||||||
|
// Initialize print page settings with default settings.
|
||||||
|
// Used only for native printing workflow.
|
||||||
|
- bool InitPrintSettings(bool fit_to_paper_size);
|
||||||
|
+ bool InitPrintSettings(bool fit_to_paper_size,
|
||||||
|
+ const base::string16& device_name = base::string16());
|
||||||
|
|
||||||
|
// Calculate number of pages in source document.
|
||||||
|
- bool CalculateNumberOfPages(blink::WebLocalFrame* frame,
|
||||||
|
- const blink::WebNode& node,
|
||||||
|
- int* number_of_pages);
|
||||||
|
+ bool CalculateNumberOfPages(
|
||||||
|
+ blink::WebLocalFrame* frame,
|
||||||
|
+ const blink::WebNode& node,
|
||||||
|
+ int* number_of_pages,
|
||||||
|
+ const base::string16& device_name = base::string16());
|
||||||
|
|
||||||
|
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||||
|
// Set options for print preset from source PDF document.
|
||||||
|
diff --git a/printing/print_settings_conversion.cc b/printing/print_settings_conversion.cc
|
||||||
|
index a4c9f49d65e0..b26eb4186880 100644
|
||||||
|
--- a/printing/print_settings_conversion.cc
|
||||||
|
+++ b/printing/print_settings_conversion.cc
|
||||||
|
@@ -42,6 +42,19 @@ void GetCustomMarginsFromJobSettings(const base::DictionaryValue& settings,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+void SetCustomMarginsToJobSettings(const PageSizeMargins& page_size_margins,
|
||||||
|
+ base::DictionaryValue* settings) {
|
||||||
|
+ std::unique_ptr<base::DictionaryValue> custom_margins(
|
||||||
|
+ new base::DictionaryValue());
|
||||||
|
+ custom_margins->SetDouble(kSettingMarginTop, page_size_margins.margin_top);
|
||||||
|
+ custom_margins->SetDouble(kSettingMarginBottom,
|
||||||
|
+ page_size_margins.margin_bottom);
|
||||||
|
+ custom_margins->SetDouble(kSettingMarginLeft, page_size_margins.margin_left);
|
||||||
|
+ custom_margins->SetDouble(kSettingMarginRight,
|
||||||
|
+ page_size_margins.margin_right);
|
||||||
|
+ settings->Set(kSettingMarginsCustom, std::move(custom_margins));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void SetMarginsToJobSettings(const std::string& json_path,
|
||||||
|
const PageMargins& margins,
|
||||||
|
base::DictionaryValue* job_settings) {
|
||||||
|
@@ -224,6 +237,72 @@ bool PrintSettingsFromJobSettings(const base::DictionaryValue& job_settings,
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
+void PrintSettingsToJobSettings(const PrintSettings& settings,
|
||||||
|
+ base::DictionaryValue* job_settings) {
|
||||||
|
+ // header footer
|
||||||
|
+ job_settings->SetBoolean(kSettingHeaderFooterEnabled,
|
||||||
|
+ settings.display_header_footer());
|
||||||
|
+ job_settings->SetString(kSettingHeaderFooterTitle, settings.title());
|
||||||
|
+ job_settings->SetString(kSettingHeaderFooterURL, settings.url());
|
||||||
|
+
|
||||||
|
+ // bg
|
||||||
|
+ job_settings->SetBoolean(kSettingShouldPrintBackgrounds,
|
||||||
|
+ settings.should_print_backgrounds());
|
||||||
|
+ job_settings->SetBoolean(kSettingShouldPrintSelectionOnly,
|
||||||
|
+ settings.selection_only());
|
||||||
|
+
|
||||||
|
+ // margin
|
||||||
|
+ auto margin_type = settings.margin_type();
|
||||||
|
+ job_settings->SetInteger(kSettingMarginsType, settings.margin_type());
|
||||||
|
+ if (margin_type == CUSTOM_MARGINS) {
|
||||||
|
+ const auto& margins_in_points =
|
||||||
|
+ settings.requested_custom_margins_in_points();
|
||||||
|
+
|
||||||
|
+ PageSizeMargins page_size_margins;
|
||||||
|
+
|
||||||
|
+ page_size_margins.margin_top = margins_in_points.top;
|
||||||
|
+ page_size_margins.margin_bottom = margins_in_points.bottom;
|
||||||
|
+ page_size_margins.margin_left = margins_in_points.left;
|
||||||
|
+ page_size_margins.margin_right = margins_in_points.right;
|
||||||
|
+ SetCustomMarginsToJobSettings(page_size_margins, job_settings);
|
||||||
|
+ }
|
||||||
|
+ job_settings->SetInteger(kSettingPreviewPageCount, 1);
|
||||||
|
+
|
||||||
|
+ // range
|
||||||
|
+
|
||||||
|
+ if (!settings.ranges().empty()) {
|
||||||
|
+ auto page_range_array = std::make_unique<base::ListValue>();
|
||||||
|
+ job_settings->Set(kSettingPageRange, std::move(page_range_array));
|
||||||
|
+ for (size_t i = 0; i < settings.ranges().size(); ++i) {
|
||||||
|
+ std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
|
||||||
|
+ dict->SetInteger(kSettingPageRangeFrom, settings.ranges()[i].from + 1);
|
||||||
|
+ dict->SetInteger(kSettingPageRangeTo, settings.ranges()[i].to + 1);
|
||||||
|
+ page_range_array->Append(std::move(dict));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ job_settings->SetBoolean(kSettingCollate, settings.collate());
|
||||||
|
+ job_settings->SetInteger(kSettingCopies, 1);
|
||||||
|
+ job_settings->SetInteger(kSettingColor, settings.color());
|
||||||
|
+ job_settings->SetInteger(kSettingDuplexMode, settings.duplex_mode());
|
||||||
|
+ job_settings->SetBoolean(kSettingLandscape, settings.landscape());
|
||||||
|
+ job_settings->SetString(kSettingDeviceName, settings.device_name());
|
||||||
|
+ job_settings->SetInteger(kSettingScaleFactor, 100);
|
||||||
|
+ job_settings->SetBoolean("rasterizePDF", false);
|
||||||
|
+
|
||||||
|
+ job_settings->SetInteger("dpi", settings.dpi());
|
||||||
|
+ job_settings->SetInteger("dpiHorizontal", 72);
|
||||||
|
+ job_settings->SetInteger("dpiVertical", 72);
|
||||||
|
+
|
||||||
|
+ job_settings->SetBoolean(kSettingPrintToPDF, false);
|
||||||
|
+ job_settings->SetBoolean(kSettingCloudPrintDialog, false);
|
||||||
|
+ job_settings->SetBoolean(kSettingPrintWithPrivet, false);
|
||||||
|
+ job_settings->SetBoolean(kSettingPrintWithExtension, false);
|
||||||
|
+
|
||||||
|
+ job_settings->SetBoolean(kSettingShowSystemDialog, false);
|
||||||
|
+ job_settings->SetInteger(kSettingPreviewPageCount, 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void PrintSettingsToJobSettingsDebug(const PrintSettings& settings,
|
||||||
|
base::DictionaryValue* job_settings) {
|
||||||
|
job_settings->SetBoolean(kSettingHeaderFooterEnabled,
|
||||||
|
diff --git a/printing/print_settings_conversion.h b/printing/print_settings_conversion.h
|
||||||
|
index 283c0ff81954..231873a45644 100644
|
||||||
|
--- a/printing/print_settings_conversion.h
|
||||||
|
+++ b/printing/print_settings_conversion.h
|
||||||
|
@@ -21,6 +21,10 @@ PRINTING_EXPORT bool PrintSettingsFromJobSettings(
|
||||||
|
const base::DictionaryValue& job_settings,
|
||||||
|
PrintSettings* print_settings);
|
||||||
|
|
||||||
|
+PRINTING_EXPORT void PrintSettingsToJobSettings(
|
||||||
|
+ const PrintSettings& settings,
|
||||||
|
+ base::DictionaryValue* job_settings);
|
||||||
|
+
|
||||||
|
// Use for debug only, because output is not completely consistent with format
|
||||||
|
// of |PrintSettingsFromJobSettings| input.
|
||||||
|
void PrintSettingsToJobSettingsDebug(const PrintSettings& settings,
|
Loading…
Reference in a new issue