// Copyright 2015 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "components/printing/browser/print_manager.h" #include "base/bind.h" #include "build/build_config.h" #include "content/public/browser/render_frame_host.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" namespace printing { PrintManager::PrintManager(content::WebContents* contents) : content::WebContentsObserver(contents), print_manager_host_receivers_(contents, this) {} PrintManager::~PrintManager() = default; void PrintManager::BindReceiver( mojo::PendingAssociatedReceiver receiver, content::RenderFrameHost* rfh) { print_manager_host_receivers_.Bind(rfh, std::move(receiver)); } void PrintManager::RenderFrameDeleted( content::RenderFrameHost* render_frame_host) { print_render_frames_.erase(render_frame_host); } void PrintManager::DidGetPrintedPagesCount(int32_t cookie, uint32_t number_pages) { DCHECK_GT(cookie, 0); DCHECK_GT(number_pages, 0u); number_pages_ = number_pages; } void PrintManager::DidShowPrintDialog() {} void PrintManager::DidPrintDocument(mojom::DidPrintDocumentParamsPtr params, DidPrintDocumentCallback callback) { std::move(callback).Run(false); } void PrintManager::ShowInvalidPrinterSettingsError() {} void PrintManager::PrintingFailed(int32_t cookie, mojom::PrintFailureReason reason) { // Note: Not redundant with cookie checks in the same method in other parts of // the class hierarchy. if (!IsValidCookie(cookie)) return; #if BUILDFLAG(IS_ANDROID) PdfWritingDone(0); #endif } void PrintManager::ClearPrintRenderFramesForTesting() { print_render_frames_.clear(); } bool PrintManager::IsPrintRenderFrameConnected( content::RenderFrameHost* rfh) const { auto it = print_render_frames_.find(rfh); return it != print_render_frames_.end() && it->second.is_bound() && it->second.is_connected(); } const mojo::AssociatedRemote& PrintManager::GetPrintRenderFrame(content::RenderFrameHost* rfh) { // This is a safety CHECK() to protect against future regressions where a // caller forgets to check `IsRenderFrameLive()`. Entries are removed from // `print_render_frames_` by RenderFrameDeleted(), which may never be called // if the RenderFrameHost does not currently have a live RenderFrame. // // While this CHECK() could be moved into the two conditional branches below // that actually bind the remote, it does not really make sense to send an IPC // to a non-live RenderFrame. CHECK(rfh->IsRenderFrameLive()); auto it = print_render_frames_.find(rfh); if (it == print_render_frames_.end()) { mojo::AssociatedRemote remote; rfh->GetRemoteAssociatedInterfaces()->GetInterface(&remote); it = print_render_frames_.insert({rfh, std::move(remote)}).first; } else if (it->second.is_bound() && !it->second.is_connected()) { // When print preview is closed, the remote is disconnected from the // receiver. Reset and bind the remote before using it again. it->second.reset(); rfh->GetRemoteAssociatedInterfaces()->GetInterface(&it->second); } return it->second; } content::RenderFrameHost* PrintManager::GetCurrentTargetFrame() { return print_manager_host_receivers_.GetCurrentTargetFrame(); } void PrintManager::PrintingRenderFrameDeleted() { #if BUILDFLAG(IS_ANDROID) PdfWritingDone(0); #endif } bool PrintManager::IsValidCookie(int cookie) const { return cookie > 0 && cookie == cookie_; } } // namespace printing