123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- // Copyright 2015 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "android_webview/browser/aw_print_manager.h"
- #include <utility>
- #include "base/bind.h"
- #include "base/file_descriptor_posix.h"
- #include "base/files/file_util.h"
- #include "base/memory/ptr_util.h"
- #include "base/memory/ref_counted_memory.h"
- #include "base/numerics/safe_conversions.h"
- #include "base/task/task_traits.h"
- #include "base/task/thread_pool.h"
- #include "components/printing/browser/print_manager_utils.h"
- #include "components/printing/common/print.mojom.h"
- #include "content/public/browser/browser_thread.h"
- #include "content/public/browser/render_frame_host.h"
- #include "printing/print_job_constants.h"
- namespace android_webview {
- namespace {
- uint32_t SaveDataToFd(int fd,
- uint32_t page_count,
- scoped_refptr<base::RefCountedSharedMemoryMapping> data) {
- bool result = fd > base::kInvalidFd &&
- base::IsValueInRangeForNumericType<int>(data->size());
- if (result)
- result = base::WriteFileDescriptor(fd, *data);
- return result ? page_count : 0;
- }
- } // namespace
- AwPrintManager::AwPrintManager(content::WebContents* contents)
- : PrintManager(contents),
- content::WebContentsUserData<AwPrintManager>(*contents) {}
- AwPrintManager::~AwPrintManager() = default;
- // static
- void AwPrintManager::BindPrintManagerHost(
- mojo::PendingAssociatedReceiver<printing::mojom::PrintManagerHost> receiver,
- content::RenderFrameHost* rfh) {
- auto* web_contents = content::WebContents::FromRenderFrameHost(rfh);
- if (!web_contents)
- return;
- auto* print_manager = AwPrintManager::FromWebContents(web_contents);
- if (!print_manager)
- return;
- print_manager->BindReceiver(std::move(receiver), rfh);
- }
- void AwPrintManager::PdfWritingDone(int page_count) {
- pdf_writing_done_callback().Run(page_count);
- // Invalidate the file descriptor so it doesn't get reused.
- fd_ = -1;
- }
- bool AwPrintManager::PrintNow() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- auto* rfh = web_contents()->GetPrimaryMainFrame();
- if (!rfh->IsRenderFrameLive())
- return false;
- GetPrintRenderFrame(rfh)->PrintRequestedPages();
- return true;
- }
- void AwPrintManager::GetDefaultPrintSettings(
- GetDefaultPrintSettingsCallback callback) {
- // Unlike PrintViewManagerBase, we do process this in UI thread.
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- auto params = printing::mojom::PrintParams::New();
- printing::RenderParamsFromPrintSettings(*settings_, params.get());
- params->document_cookie = cookie();
- std::move(callback).Run(std::move(params));
- }
- void AwPrintManager::UpdateParam(
- std::unique_ptr<printing::PrintSettings> settings,
- int file_descriptor,
- PrintManager::PdfWritingDoneCallback callback) {
- DCHECK(settings);
- DCHECK(callback);
- settings_ = std::move(settings);
- fd_ = file_descriptor;
- set_pdf_writing_done_callback(std::move(callback));
- set_cookie(1); // Set a valid dummy cookie value.
- }
- void AwPrintManager::ScriptedPrint(
- printing::mojom::ScriptedPrintParamsPtr scripted_params,
- ScriptedPrintCallback callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- auto params = printing::mojom::PrintPagesParams::New();
- params->params = printing::mojom::PrintParams::New();
- if (scripted_params->is_scripted &&
- GetCurrentTargetFrame()->IsNestedWithinFencedFrame()) {
- DLOG(ERROR) << "Unexpected message received. Script Print is not allowed"
- " in a fenced frame.";
- std::move(callback).Run(std::move(params));
- return;
- }
- printing::RenderParamsFromPrintSettings(*settings_, params->params.get());
- params->params->document_cookie = scripted_params->cookie;
- params->pages = settings_->ranges();
- std::move(callback).Run(std::move(params));
- }
- void AwPrintManager::DidPrintDocument(
- printing::mojom::DidPrintDocumentParamsPtr params,
- DidPrintDocumentCallback callback) {
- if (params->document_cookie != cookie()) {
- std::move(callback).Run(false);
- return;
- }
- const printing::mojom::DidPrintContentParams& content = *params->content;
- if (!content.metafile_data_region.IsValid()) {
- NOTREACHED() << "invalid memory handle";
- web_contents()->Stop();
- PdfWritingDone(0);
- std::move(callback).Run(false);
- return;
- }
- auto data = base::RefCountedSharedMemoryMapping::CreateFromWholeRegion(
- content.metafile_data_region);
- if (!data) {
- NOTREACHED() << "couldn't map";
- web_contents()->Stop();
- PdfWritingDone(0);
- std::move(callback).Run(false);
- return;
- }
- if (number_pages() > printing::kMaxPageCount) {
- web_contents()->Stop();
- PdfWritingDone(0);
- std::move(callback).Run(false);
- return;
- }
- DCHECK(pdf_writing_done_callback());
- base::PostTaskAndReplyWithResult(
- base::ThreadPool::CreateTaskRunner(
- {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
- base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})
- .get(),
- FROM_HERE, base::BindOnce(&SaveDataToFd, fd_, number_pages(), data),
- base::BindOnce(&AwPrintManager::OnDidPrintDocumentWritingDone,
- pdf_writing_done_callback(), std::move(callback)));
- }
- // static
- void AwPrintManager::OnDidPrintDocumentWritingDone(
- const PdfWritingDoneCallback& callback,
- DidPrintDocumentCallback did_print_document_cb,
- uint32_t page_count) {
- DCHECK_LE(page_count, printing::kMaxPageCount);
- if (callback)
- callback.Run(base::checked_cast<int>(page_count));
- std::move(did_print_document_cb).Run(true);
- }
- WEB_CONTENTS_USER_DATA_KEY_IMPL(AwPrintManager);
- } // namespace android_webview
|