electron/shell/browser/printing/print_preview_message_handler.cc
Electron Bot dc72f74020
chore: bump chromium to 580fe983e138952553cd6af11ee8b (master) (#23379)
* chore: bump chromium in DEPS to 5ce64b91b4d6a78c97480059f15ff6469fc0918e

* chore: bump chromium in DEPS to e74c73d0000f81b3f40a513176c8d024bba57d28

* chore: bump chromium in DEPS to 501640e650d4657ba63db65fa257e4a899168de7

* chore: bump chromium in DEPS to 00db20e1bc3d77706723a87ada3c1c647a1c37b7

* chore: update patches

* refactor: AddNewContents now takes a target_url

Refs: https://chromium-review.googlesource.com/c/chromium/src/+/2167732

* chore: SetHostCleanupFinalizationGroupCallback has been removed from V8

* refactor: use WebInputEvent::Namespace types directly

Refs: https://chromium-review.googlesource.com/c/chromium/src/+/2160523

* refactor: FollowRedirect takes in cors exempt headers now

Refs: https://chromium-review.googlesource.com/c/chromium/src/+/2129787

* refactor: printing::DuplexMode moved to mojo

Refs: https://chromium-review.googlesource.com/c/chromium/src/+/2162388

* refactor: use MessagePortDescriptor instead of raw mojo::MessagePipeHandles

Refs: https://chromium-review.googlesource.com/c/chromium/src/+/1952124

* chore: update patches

* chore: bump chromium in DEPS to f1537676d613f3567cfb43adf577b3847fba4bc3

* chore: update patches

* refactor: service_manager::BinderMapWithContext merged into mojo::BinderMap

Refs: https://chromium-review.googlesource.com/c/chromium/src/+/2174654

* chore: unused argument removed from ReadAvailableTypes in ui::Clipboard

Refs: https://chromium-review.googlesource.com/c/chromium/src/+/2173666

* chore: bump chromium in DEPS to 949888433ab935dd6125c107226a4c9d6da9bf48

* chore: update patches

* update patches

* chore: update sysroots

* chore: bump chromium in DEPS to eaac5b5035fe189b6706e1637122e37134206059

* chore: bump chromium in DEPS to 258b54b903d33dab963adf59016691e6537f8b70

* build: update patches

* refactor: cursor.mojom and cursor_types.mojom moved to //ui/base/cursor/mojom

Refs: https://chromium-review.googlesource.com/c/chromium/src/+/2172874

* chore: DesktopWindowTreeHostLinux becomes DesktopWindowTreeHostPlatform

Refs:

* refactor: LogErrorEventDescription moved from ui to x11

Refs: https://chromium-review.googlesource.com/c/chromium/src/+/2164245

* chore: update patches

* chore: bump chromium in DEPS to bd06abcfe807d4461683479237cdd920dafa52ca

* chore: bump chromium in DEPS to 1afb0891e56f1e79d204db43ca053a46d0974511

* chore: bump chromium in DEPS to 5cb0f794bf7f155bf8c0a241b94e01c9d90c2744

* chore: bump chromium in DEPS to 37327ba3303234e1a3cd3310ca11a68e81b95123

* update patches

* remove ClientSideDetectionService from browser_process

Refs: https://chromium-review.googlesource.com/c/chromium/src/+/2175320

* refactor: shuttle cursor changed event to WebContentsObserver

Refs: https://chromium-review.googlesource.com/c/chromium/src/+/2172779

* chore: bump chromium in DEPS to 1d97904bb6936e106df13705208b73e47367c2b9

* avoid IPC crash introduced earlier in the roll

Refs: b67334e781 (diff-607f4e8f7c5686aa09af98c783925babR128)

* remove WebContentsView::SizeContents

Refs: https://chromium-review.googlesource.com/c/chromium/src/+/2188931

* chore: bump chromium in DEPS to 87066d1db0546a9de33952ba964e1e42f76f1dae

* update patches

* adapt to //content creating NetworkContexts

https://chromium-review.googlesource.com/c/chromium/src/+/2195196

* WIP temporarily ignore mojo-ified PrintHostMsg_PrintPreviewFailed

Refs: https://chromium-review.googlesource.com/c/chromium/src/+/2195343

* add checkout_pgo_profiles to DEPS

* chore: bump chromium in DEPS to a095318bec1dedf580d676f408eaeefdbd9956b1

* add blink's execution_context to electron_lib deps

Refs:
b67334e781#, https://chromium-review.googlesource.com/c/chromium/src/+/1952124

* update patches

* update patches

* refactor: use newly mojo-ified PrintPreviewFailed

Refs: https://chromium-review.googlesource.com/c/chromium/src/+/2195343
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* chore: update patches

* chore: remove NOTIFICATION_EXTENSIONS_READY_DEPRECATED

Refs: https://chromium-review.googlesource.com/c/chromium/src/+/2199874

* avoid a call to Profile::FromBrowserContext in printing

Refs: https://chromium-review.googlesource.com/c/chromium/src/+/2195757

* chore: bump chromium in DEPS to 8f5c6a46861a991e12ffd80554b6bd41a11b0b65

* chore: bump chromium in DEPS to ab66134739ff3b6bdb8de53bbc58a97d1b7b5d8a

* chore: bump chromium in DEPS to dd08df9f6c8d6198f0a7b931ca9e845e27dae033

* chore: update patches

* [printing] Mojofy PrintHostMsg_PrintPreviewCancelled

https://chromium-review.googlesource.com/c/chromium/src/+/2198331

* [printing] Mojofy PrintHostMsg_PrintPreviewInvalidPrinterSettings

https://chromium-review.googlesource.com/c/chromium/src/+/2200556

* [printing] Mojofy PrintHostMsg_DidPrepareDocumentForPreview

https://chromium-review.googlesource.com/c/chromium/src/+/2201496

* fix: inherit base network context params

* fix: use message handle api specific to embedders

* update patches

* chore: update v8 headers

* fixup! avoid a call to Profile::FromBrowserContext in printing

* chore: bump chromium in DEPS to f198bc3276828d992b6202d75a9da6a8363164ea

* chore: update patches

* Remove cors_exempt_headers.h

https://chromium-review.googlesource.com/c/chromium/src/+/2203759

* Supply speech recognition sandbox from service_sandbox_type.h

https://chromium-review.googlesource.com/c/chromium/src/+/2206918

* [content] Remove unused methods from WebContents

https://chromium-review.googlesource.com/c/chromium/src/+/2199113

* [XProto] Replace XAtom with x11::Atom

https://chromium-review.googlesource.com/c/chromium/src/+/2202789

* chore: bump chromium in DEPS to 5df37fabaaed09f3ea511f4ef49203d8ebee7b68

* [UI] Support secondary labels in dropdown menus

https://chromium-review.googlesource.com/c/chromium/src/+/2208976

* chore: update patches

* refactor: GetSublabelAt => GetSecondaryLabelAt

* Revert "[printing] Mojofy PrintHostMsg_DidPrepareDocumentForPreview"

This reverts commit 44ed0892a0c81716229638f17253bbb2cf8f037d.

https://chromium-review.googlesource.com/c/chromium/src/+/2208778

* Unnest CanonicalCookie::CookieInclusionStatus

https://chromium-review.googlesource.com/c/chromium/src/+/2203171

* update print-to-pdf.html with latest html data

https://bugs.chromium.org/p/chromium/issues/detail?id=1085667

* chore: bump chromium in DEPS to 5dfa8d5f706580fe983e138952553cd6af11ee8b

* fix crash in x server when setting window icon

* chore: update patches

* Use a normal return value for WebContentsView::GetContainerBounds.

https://chromium-review.googlesource.com/c/chromium/src/+/2212481

* fix build on windows

* chore: bump chromium in DEPS to 9d15054f4cba060901e43deecf74002f11f47be3

* chore: update patches

* [printing] Mojofy PrintHostMsg_CheckForCancel

https://chromium-review.googlesource.com/c/chromium/src/+/2212181

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: Electron Bot <anonymous@electronjs.org>
Co-authored-by: Andy Locascio <andy@slack-corp.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2020-05-26 13:06:26 -07:00

211 lines
7.1 KiB
C++

// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/browser/printing/print_preview_message_handler.h"
#include <memory>
#include <utility>
#include "base/bind.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/ref_counted.h"
#include "base/memory/ref_counted_memory.h"
#include "base/task/post_task.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/printing/print_job_manager.h"
#include "chrome/browser/printing/printer_query.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/print_compositor/public/cpp/print_service_mojo_types.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "mojo/public/cpp/bindings/callback_helpers.h"
#include "shell/common/gin_helper/locker.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "shell/common/node_includes.h"
using content::BrowserThread;
namespace electron {
namespace {
void StopWorker(int document_cookie) {
if (document_cookie <= 0)
return;
scoped_refptr<printing::PrintQueriesQueue> queue =
g_browser_process->print_job_manager()->queue();
std::unique_ptr<printing::PrinterQuery> printer_query =
queue->PopPrinterQuery(document_cookie);
if (printer_query.get()) {
base::PostTask(FROM_HERE, {BrowserThread::IO},
base::BindOnce(&printing::PrinterQuery::StopWorker,
std::move(printer_query)));
}
}
} // namespace
PrintPreviewMessageHandler::PrintPreviewMessageHandler(
content::WebContents* web_contents)
: content::WebContentsObserver(web_contents), weak_ptr_factory_(this) {
DCHECK(web_contents);
}
PrintPreviewMessageHandler::~PrintPreviewMessageHandler() = default;
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)
IPC_MESSAGE_HANDLER(PrintHostMsg_MetafileReadyForPrinting,
OnMetafileReadyForPrinting)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void PrintPreviewMessageHandler::OnMetafileReadyForPrinting(
content::RenderFrameHost* render_frame_host,
const PrintHostMsg_DidPreviewDocument_Params& params,
const PrintHostMsg_PreviewIds& ids) {
// Always try to stop the worker.
StopWorker(params.document_cookie);
const PrintHostMsg_DidPrintContent_Params& content = params.content;
if (!content.metafile_data_region.IsValid() ||
params.expected_pages_count <= 0) {
RejectPromise(ids.request_id);
return;
}
if (printing::IsOopifEnabled()) {
auto* client =
printing::PrintCompositeClient::FromWebContents(web_contents());
DCHECK(client);
auto callback =
base::BindOnce(&PrintPreviewMessageHandler::OnCompositePdfDocumentDone,
weak_ptr_factory_.GetWeakPtr(), ids);
client->DoCompositeDocumentToPdf(
params.document_cookie, render_frame_host, content,
mojo::WrapCallbackWithDefaultInvokeIfNotRun(
std::move(callback),
printing::mojom::PrintCompositor::Status::kCompositingFailure,
base::ReadOnlySharedMemoryRegion()));
} else {
ResolvePromise(ids.request_id,
base::RefCountedSharedMemoryMapping::CreateFromWholeRegion(
content.metafile_data_region));
}
}
void PrintPreviewMessageHandler::OnCompositePdfDocumentDone(
const PrintHostMsg_PreviewIds& ids,
printing::mojom::PrintCompositor::Status status,
base::ReadOnlySharedMemoryRegion region) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (status != printing::mojom::PrintCompositor::Status::kSuccess) {
DLOG(ERROR) << "Compositing pdf failed with error " << status;
RejectPromise(ids.request_id);
return;
}
ResolvePromise(
ids.request_id,
base::RefCountedSharedMemoryMapping::CreateFromWholeRegion(region));
}
void PrintPreviewMessageHandler::PrintPreviewFailed(int32_t document_cookie,
int32_t request_id) {
StopWorker(document_cookie);
RejectPromise(request_id);
}
void PrintPreviewMessageHandler::PrintPreviewCancelled(int32_t document_cookie,
int32_t request_id) {
StopWorker(document_cookie);
RejectPromise(request_id);
}
void PrintPreviewMessageHandler::CheckForCancel(
int32_t request_id,
CheckForCancelCallback callback) {
std::move(callback).Run(false);
}
void PrintPreviewMessageHandler::PrintToPDF(
base::DictionaryValue options,
gin_helper::Promise<v8::Local<v8::Value>> promise) {
int request_id;
options.GetInteger(printing::kPreviewRequestID, &request_id);
promise_map_.emplace(request_id, std::move(promise));
auto* focused_frame = web_contents()->GetFocusedFrame();
auto* rfh = focused_frame && focused_frame->HasSelection()
? focused_frame
: web_contents()->GetMainFrame();
if (!print_render_frame_.is_bound()) {
rfh->GetRemoteAssociatedInterfaces()->GetInterface(&print_render_frame_);
}
if (!receiver_.is_bound()) {
print_render_frame_->SetPrintPreviewUI(
receiver_.BindNewEndpointAndPassRemote());
}
print_render_frame_->PrintPreview(options.Clone());
}
gin_helper::Promise<v8::Local<v8::Value>>
PrintPreviewMessageHandler::GetPromise(int request_id) {
auto it = promise_map_.find(request_id);
DCHECK(it != promise_map_.end());
gin_helper::Promise<v8::Local<v8::Value>> promise = std::move(it->second);
promise_map_.erase(it);
return promise;
}
void PrintPreviewMessageHandler::ResolvePromise(
int request_id,
scoped_refptr<base::RefCountedMemory> data_bytes) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
gin_helper::Promise<v8::Local<v8::Value>> promise = GetPromise(request_id);
v8::Isolate* isolate = promise.isolate();
gin_helper::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
v8::Context::Scope context_scope(
v8::Local<v8::Context>::New(isolate, promise.GetContext()));
v8::Local<v8::Value> buffer =
node::Buffer::Copy(isolate,
reinterpret_cast<const char*>(data_bytes->front()),
data_bytes->size())
.ToLocalChecked();
promise.Resolve(buffer);
}
void PrintPreviewMessageHandler::RejectPromise(int request_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
gin_helper::Promise<v8::Local<v8::Value>> promise = GetPromise(request_id);
promise.RejectWithErrorMessage("Failed to generate PDF");
}
WEB_CONTENTS_USER_DATA_KEY_IMPL(PrintPreviewMessageHandler)
} // namespace electron