electron/shell/browser/printing/print_preview_message_handler.cc
electron-roller[bot] 90af7d7fe2
chore: bump chromium to 111.0.5518.0 (main) (#36575)
* chore: bump chromium in DEPS to 110.0.5461.0

* chore: update patches

* 3903024: hid: Add connection count tracking methods for HidDelegate

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

* 4076211: Turn FrameTreeNode::frame_tree into raw_ref.

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

* chore: bump chromium in DEPS to 110.0.5463.0

* chore: bump chromium in DEPS to 110.0.5465.0

* fix patches

* 3835037: Add new slides media session actions to Picture-in-Picture window

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

* chore: update patches

* chore: bump chromium in DEPS to 110.0.5467.0

* chore: update patches

* chore: bump chromium in DEPS to 110.0.5469.0

* chore: bump chromium in DEPS to 110.0.5471.0

* chore: bump chromium in DEPS to 110.0.5473.0

* chore: bump chromium in DEPS to 110.0.5475.0

* chore: update patches

* 4074449: Add gl::FrameData to software path

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

* 4065264: [Extensions] Add a new side panel view type

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

* 4060548: Remove base::Value::GetListDeprecated().

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

* chore: add missing RefCountedMemory include

* 4081108: task posting v3: remove task_runner_util{.h,_unittest.cc}

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

* 4072471: Rename Mixed Download Blocking to Insecure Download Blocking

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

* 4025927: [Code Health] Migrate e/c/manifest.cc to base::Value::Dict interface

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

* chore: fixup patch indices

* chore: bump chromium in DEPS to 110.0.5477.0

* chore: fixup preconnect_manager.patch

* chore: fixup patch indices

* fixup! 4074449: Add gl::FrameData to software path

* 4074449: Add gl::FrameData to software path

This commit also reformatted the two files in this patch. The only
change here is the addition of the |data| arg to |OnSwapBuffers|.

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

* 4081108: task posting v3: remove task_runner_util{.h,_unittest.cc}

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

* 4085814: [Test Automation] Move NativeWindowTracker to ui/views

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

* 4032656: hid: Abstract HidSystemTrayIcon class for profiles' HID connections

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

* chore: bump chromium in DEPS to 110.0.5479.0

* chore: fixup patches & simplify printing patch

To be specific, I replaced some combination of line removals &
commenting-out with `#if 0` blocks since they were already there for
android.

Should be functionally the same, just written differently for better
patch maintainability.

* chore: bump chromium in DEPS to 110.0.5481.0

* chore: update patch indicies

* 4098946: Migrate Extension::Create() argument to base::Value::Dict (part 4 of 4)

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

* chore: bump chromium in DEPS to 111.0.5482.0

* chore: bump chromium in DEPS to 111.0.5484.0

* chore: bump chromium in DEPS to 111.0.5486.0

* chore: update patch indices

* 4112903: Reland "Move gl::FrameData to gfx::FrameData"

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

* 4056216: Option to create a tab target with Target.createTarget in /json/new

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

* chore: bump chromium in DEPS to 111.0.5488.0

* chore: bump chromium in DEPS to 111.0.5490.0

* chore: bump chromium in DEPS to 111.0.5492.0

* chore: bump chromium in DEPS to 111.0.5494.0

* chore: bump chromium in DEPS to 111.0.5496.0

* chore: bump chromium in DEPS to 111.0.5498.0

* chore: bump chromium in DEPS to 111.0.5500.0

* chore: bump chromium in DEPS to 111.0.5502.0

* chore: update patch indices

+ small update to printing.patch due to:
3653941: [printing] Extract settings logic from PrintJobWorker
https://chromium-review.googlesource.com/c/chromium/src/+/3653941

* 4113994: Cleanup: Rename webui_generated_resources_* to webui_resources_*.
https://chromium-review.googlesource.com/c/chromium/src/+/4113994

* 4112537: Remove DictionaryPrefUpdate.
https://chromium-review.googlesource.com/c/chromium/src/+/4112537

* 4072073: Remove //chrome/browser/ash dependency from pdf_extension_util.cc
https://chromium-review.googlesource.com/c/chromium/src/+/4072073

* 4055223: [Remove FileSystemConnector] Remove DownloadItemRerouteInfo
https://chromium-review.googlesource.com/c/chromium/src/+/4055223

* Migrate base::DictionaryValue to base::Value::Dict

This relates to multiple CLs cleaning up this class in this roll,
but the ones that are specifically relevant here:

4116096: [CodeHealth] Remove DictionaryValue::GetInteger
https://chromium-review.googlesource.com/c/chromium/src/+/4116096

4113764: [CodeHealth] Remove deprecated DictionaryValue::SetInteger()
https://chromium-review.googlesource.com/c/chromium/src/+/4113764

* 3653941: [printing] Extract settings logic from PrintJobWorker
https://chromium-review.googlesource.com/c/chromium/src/+/3653941

* chore: bump chromium in DEPS to 111.0.5504.0

* chore: update patches

* (WIP) 4003663: Enable Microtask queues per WindowAgent.

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

* chore: bump chromium in DEPS to 111.0.5506.0

* chore: update patches

* fix: printing patch

It was complaining that this method isn't used on windows

* chore: bump chromium in DEPS to 111.0.5508.0

* chore: bump chromium in DEPS to 111.0.5510.0

* chore: bump chromium in DEPS to 111.0.5512.0

* chore: bump chromium in DEPS to 111.0.5514.0

* chore: bump chromium in DEPS to 111.0.5516.0

* chore: update patches

* chore: bump chromium in DEPS to 111.0.5518.0

* chore: update patches

* 4027428: [rsafor] Move rsaFor requests to a separate permission

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

* Revert "(WIP) 4003663: Enable Microtask queues per WindowAgent."

This reverts commit cc36d226e3f3fe5f4bea6538102d55ce3203190f.

* chore: disable Microtask queues per WindowAgent.

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

* chore: cleanup after rebase

* fixup: disable Microtask queues per WindowAgent.

* chore: cleanup password from keychain after test

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: Calvin Watford <cwatford@slack-corp.com>
Co-authored-by: clavin <clavin@electronjs.org>
2023-01-05 21:35:34 -05:00

273 lines
9.2 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 "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/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 "content/public/browser/web_contents_user_data.h"
#include "mojo/public/cpp/bindings/callback_helpers.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()) {
content::GetIOThreadTaskRunner({})->PostTask(
FROM_HERE, base::BindOnce(&printing::PrinterQuery::StopWorker,
std::move(printer_query)));
}
}
} // namespace
PrintPreviewMessageHandler::PrintPreviewMessageHandler(
content::WebContents* web_contents)
: content::WebContentsUserData<PrintPreviewMessageHandler>(*web_contents),
web_contents_(web_contents) {
DCHECK(web_contents);
}
PrintPreviewMessageHandler::~PrintPreviewMessageHandler() = default;
void PrintPreviewMessageHandler::MetafileReadyForPrinting(
printing::mojom::DidPreviewDocumentParamsPtr params,
int32_t request_id) {
// Always try to stop the worker.
StopWorker(params->document_cookie);
if (params->expected_pages_count == 0) {
RejectPromise(request_id);
return;
}
const base::ReadOnlySharedMemoryRegion& metafile =
params->content->metafile_data_region;
if (printing::IsOopifEnabled()) {
auto* client =
printing::PrintCompositeClient::FromWebContents(web_contents_);
DCHECK(client);
auto callback = base::BindOnce(
&PrintPreviewMessageHandler::OnCompositeDocumentToPdfDone,
weak_ptr_factory_.GetWeakPtr(), request_id);
client->DoCompleteDocumentToPdf(
params->document_cookie, params->expected_pages_count,
mojo::WrapCallbackWithDefaultInvokeIfNotRun(
std::move(callback),
printing::mojom::PrintCompositor::Status::kCompositingFailure,
base::ReadOnlySharedMemoryRegion()));
} else {
ResolvePromise(
request_id,
base::RefCountedSharedMemoryMapping::CreateFromWholeRegion(metafile));
}
}
void PrintPreviewMessageHandler::OnPrepareForDocumentToPdfDone(
int32_t request_id,
printing::mojom::PrintCompositor::Status status) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (status != printing::mojom::PrintCompositor::Status::kSuccess) {
LOG(ERROR) << "Preparing document for pdf failed with error " << status;
}
}
void PrintPreviewMessageHandler::DidPrepareDocumentForPreview(
int32_t document_cookie,
int32_t request_id) {
if (printing::IsOopifEnabled()) {
auto* client =
printing::PrintCompositeClient::FromWebContents(web_contents_);
DCHECK(client);
if (client->GetIsDocumentConcurrentlyComposited(document_cookie))
return;
auto* focused_frame = web_contents_->GetFocusedFrame();
auto* rfh = focused_frame && focused_frame->HasSelection()
? focused_frame
: web_contents_->GetPrimaryMainFrame();
client->DoPrepareForDocumentToPdf(
document_cookie, rfh,
mojo::WrapCallbackWithDefaultInvokeIfNotRun(
base::BindOnce(
&PrintPreviewMessageHandler::OnPrepareForDocumentToPdfDone,
weak_ptr_factory_.GetWeakPtr(), request_id),
printing::mojom::PrintCompositor::Status::kCompositingFailure));
}
}
void PrintPreviewMessageHandler::OnCompositeDocumentToPdfDone(
int32_t request_id,
printing::mojom::PrintCompositor::Status status,
base::ReadOnlySharedMemoryRegion region) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (status != printing::mojom::PrintCompositor::Status::kSuccess) {
LOG(ERROR) << "Compositing pdf failed with error " << status;
RejectPromise(request_id);
return;
}
ResolvePromise(
request_id,
base::RefCountedSharedMemoryMapping::CreateFromWholeRegion(region));
}
void PrintPreviewMessageHandler::OnCompositePdfPageDone(
int page_number,
int document_cookie,
int32_t request_id,
printing::mojom::PrintCompositor::Status status,
base::ReadOnlySharedMemoryRegion region) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (status != printing::mojom::PrintCompositor::Status::kSuccess) {
LOG(ERROR) << "Compositing pdf failed on page: " << page_number
<< " with error: " << status;
}
}
void PrintPreviewMessageHandler::DidPreviewPage(
printing::mojom::DidPreviewPageParamsPtr params,
int32_t request_id) {
int page_number = params->page_number;
const printing::mojom::DidPrintContentParams& content = *(params->content);
if (page_number < printing::FIRST_PAGE_INDEX ||
!content.metafile_data_region.IsValid()) {
RejectPromise(request_id);
return;
}
if (printing::IsOopifEnabled()) {
auto* client =
printing::PrintCompositeClient::FromWebContents(web_contents_);
DCHECK(client);
auto* focused_frame = web_contents_->GetFocusedFrame();
auto* rfh = focused_frame && focused_frame->HasSelection()
? focused_frame
: web_contents_->GetPrimaryMainFrame();
// Use utility process to convert skia metafile to pdf.
client->DoCompositePageToPdf(
params->document_cookie, rfh, content,
mojo::WrapCallbackWithDefaultInvokeIfNotRun(
base::BindOnce(&PrintPreviewMessageHandler::OnCompositePdfPageDone,
weak_ptr_factory_.GetWeakPtr(), page_number,
params->document_cookie, request_id),
printing::mojom::PrintCompositor::Status::kCompositingFailure,
base::ReadOnlySharedMemoryRegion()));
}
}
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::PrintToPDF(
base::Value::Dict options,
gin_helper::Promise<v8::Local<v8::Value>> promise) {
int request_id;
options.Get(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_->GetPrimaryMainFrame();
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.GetDict().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();
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