blob: fb024a14b8a79d3d3a1cd0b80b821c616d2c7a17 [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/api/printing/print_job_controller.h"
#include <memory>
#include <utility>
#include "base/bind.h"
#include "base/callback.h"
#include "base/check.h"
#include "base/memory/scoped_refptr.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/printing/print_job.h"
#include "chrome/browser/printing/printer_query.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/common/child_process_host.h"
#include "printing/metafile_skia.h"
#include "printing/print_settings.h"
#include "printing/printed_document.h"
namespace extensions {
namespace {
using PrinterQueryCallback =
base::OnceCallback<void(std::unique_ptr<printing::PrinterQuery>)>;
// Send initialized PrinterQuery to UI thread.
void OnSettingsSetOnIOThread(std::unique_ptr<printing::PrinterQuery> query,
PrinterQueryCallback callback) {
content::GetUIThreadTaskRunner({})->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), std::move(query)));
}
void CreateQueryOnIOThread(std::unique_ptr<printing::PrintSettings> settings,
PrinterQueryCallback callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
auto query = std::make_unique<printing::PrinterQuery>(
content::GlobalRenderFrameHostId());
auto* query_ptr = query.get();
query_ptr->SetSettingsFromPOD(
std::move(settings),
base::BindOnce(&OnSettingsSetOnIOThread, std::move(query),
std::move(callback)));
}
void StartPrinting(scoped_refptr<printing::PrintJob> job,
const std::string& extension_id,
std::unique_ptr<printing::MetafileSkia> metafile,
std::unique_ptr<printing::PrinterQuery> query) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
// Save in separate variable because |query| is moved.
std::u16string title = query->settings().title();
job->Initialize(std::move(query), title, /*page_count=*/1);
job->SetSource(printing::PrintJob::Source::EXTENSION, extension_id);
job->document()->SetDocument(std::move(metafile));
job->StartPrinting();
}
} // namespace
// This class lives on UI thread.
class PrintJobControllerImpl : public PrintJobController {
public:
PrintJobControllerImpl() = default;
~PrintJobControllerImpl() override = default;
// PrintJobController:
scoped_refptr<printing::PrintJob> StartPrintJob(
const std::string& extension_id,
std::unique_ptr<printing::MetafileSkia> metafile,
std::unique_ptr<printing::PrintSettings> settings) override;
};
scoped_refptr<printing::PrintJob> PrintJobControllerImpl::StartPrintJob(
const std::string& extension_id,
std::unique_ptr<printing::MetafileSkia> metafile,
std::unique_ptr<printing::PrintSettings> settings) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
auto job = base::MakeRefCounted<printing::PrintJob>(
g_browser_process->print_job_manager());
content::GetIOThreadTaskRunner({})->PostTask(
FROM_HERE, base::BindOnce(&CreateQueryOnIOThread, std::move(settings),
base::BindOnce(StartPrinting, job, extension_id,
std::move(metafile))));
return job;
}
// static
std::unique_ptr<PrintJobController> PrintJobController::Create() {
return std::make_unique<PrintJobControllerImpl>();
}
} // namespace extensions