#include "chrome/browser/ui/webui/print_preview/print_preview_handler.h"
#include <stddef.h>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "ash/constants/ash_features.h"
#include "base/check.h"
#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/dcheck_is_on.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/i18n/number_formatting.h"
#include "base/json/json_reader.h"
#include "base/lazy_instance.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/app_mode/app_mode_utils.h"
#include "chrome/browser/bad_message.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/printing/background_printing_manager.h"
#include "chrome/browser/printing/prefs_util.h"
#include "chrome/browser/printing/print_error_dialog.h"
#include "chrome/browser/printing/print_job_manager.h"
#include "chrome/browser/printing/print_preview_dialog_controller.h"
#include "chrome/browser/printing/print_preview_sticky_settings.h"
#include "chrome/browser/printing/print_view_manager.h"
#include "chrome/browser/printing/printer_manager_dialog.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/chrome_pages.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/webui/print_preview/pdf_printer_handler.h"
#include "chrome/browser/ui/webui/print_preview/policy_settings.h"
#include "chrome/browser/ui/webui/print_preview/print_preview_metrics.h"
#include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
#include "chrome/browser/ui/webui/print_preview/print_preview_utils.h"
#include "chrome/browser/ui/webui/print_preview/printer_handler.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/crash_keys.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/printing/printer_capabilities.h"
#include "chrome/common/webui_url_constants.h"
#include "components/cloud_devices/common/cloud_device_description.h"
#include "components/cloud_devices/common/printer_description.h"
#include "components/enterprise/buildflags/buildflags.h"
#include "components/prefs/pref_service.h"
#include "components/printing/common/cloud_print_cdd_conversion.h"
#include "components/url_formatter/url_formatter.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "net/base/url_util.h"
#include "printing/backend/print_backend.h"
#include "printing/backend/print_backend_consts.h"
#include "printing/backend/print_backend_utils.h"
#include "printing/backend/printing_restrictions.h"
#include "printing/buildflags/buildflags.h"
#include "printing/mojom/print.mojom.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/icu/source/i18n/unicode/ulocdata.h"
#include "ui/shell_dialogs/selected_file_info.h"
#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
#include "chrome/browser/enterprise/data_protection/print_utils.h"
#if BUILDFLAG(IS_MAC)
#include "chrome/grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
#endif
#endif
#if BUILDFLAG(IS_CHROMEOS)
#include "chromeos/crosapi/mojom/local_printer.mojom.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/ash/crosapi/browser_util.h"
#include "chrome/browser/ash/crosapi/crosapi_ash.h"
#include "chrome/browser/ash/crosapi/crosapi_manager.h"
#include "chrome/browser/ash/crosapi/local_printer_ash.h"
#include "chrome/browser/ash/drive/drive_integration_service.h"
#include "chrome/browser/ui/webui/print_preview/extension_printer_handler_adapter_ash.h"
#elif BUILDFLAG(IS_CHROMEOS_LACROS)
#include "chrome/common/chrome_paths_lacros.h"
#include "chromeos/lacros/lacros_service.h"
#endif
#if DCHECK_IS_ON()
#include "base/debug/stack_trace.h"
#endif
RenderFrameHost;
WebContents;
namespace printing {
namespace {
mojom::PrinterType GetPrinterTypeForUserAction(UserActionBuckets user_action) { … }
const char kIsInKioskAutoPrintMode[] = …;
const char kIsInAppKioskMode[] = …;
const char kUiLocale[] = …;
const char kThousandsDelimiter[] = …;
const char kDecimalDelimiter[] = …;
const char kUnitType[] = …;
const char kDocumentTitle[] = …;
const char kDocumentHasSelection[] = …;
const char kAppState[] = …;
const char kDefaultDestinationSelectionRules[] = …;
const char kPolicies[] = …;
const char kAllowedMode[] = …;
const char kDefaultMode[] = …;
const char kHeaderFooter[] = …;
const char kCssBackground[] = …;
const char kMediaSize[] = …;
#if BUILDFLAG(IS_CHROMEOS)
const char kValue[] = "value";
const char kSheets[] = "sheets";
const char kColor[] = "color";
const char kDuplex[] = "duplex";
const char kPin[] = "pin";
#endif
const char kPdfPrinterDisabled[] = …;
const char kDestinationsManaged[] = …;
#if BUILDFLAG(IS_CHROMEOS)
const char kIsDriveMounted[] = "isDriveMounted";
#endif
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
const char kPrintPdfAsImageAvailability[] = "printPdfAsImageAvailability";
#endif
const char kPrintPdfAsImage[] = …;
base::Value::Dict GetSettingsDictionary(const std::string& json_str) { … }
UserActionBuckets DetermineUserAction(const base::Value::Dict& settings) { … }
#if BUILDFLAG(IS_CHROMEOS)
base::Value::Dict PoliciesToValue(crosapi::mojom::PoliciesPtr ptr) {
base::Value::Dict policies;
base::Value::Dict header_footer_policy;
if (ptr->print_header_footer_allowed !=
crosapi::mojom::Policies::OptionalBool::kUnset) {
header_footer_policy.Set(kAllowedMode,
ptr->print_header_footer_allowed ==
crosapi::mojom::Policies::OptionalBool::kTrue);
}
if (ptr->print_header_footer_default !=
crosapi::mojom::Policies::OptionalBool::kUnset) {
header_footer_policy.Set(kDefaultMode,
ptr->print_header_footer_default ==
crosapi::mojom::Policies::OptionalBool::kTrue);
}
if (!header_footer_policy.empty())
policies.Set(kHeaderFooter, std::move(header_footer_policy));
base::Value::Dict background_graphics_policy;
int value = static_cast<int>(ptr->allowed_background_graphics_modes);
if (value)
background_graphics_policy.Set(kAllowedMode, value);
value = static_cast<int>(ptr->background_graphics_default);
if (value)
background_graphics_policy.Set(kDefaultMode, value);
if (!background_graphics_policy.empty())
policies.Set(kCssBackground, std::move(background_graphics_policy));
base::Value::Dict paper_size_policy;
const std::optional<gfx::Size>& default_paper_size = ptr->paper_size_default;
if (default_paper_size.has_value()) {
base::Value::Dict default_paper_size_value;
default_paper_size_value.Set(kPaperSizeWidth,
default_paper_size.value().width());
default_paper_size_value.Set(kPaperSizeHeight,
default_paper_size.value().height());
paper_size_policy.Set(kDefaultMode, std::move(default_paper_size_value));
}
if (!paper_size_policy.empty())
policies.Set(kMediaSize, std::move(paper_size_policy));
if (ptr->max_sheets_allowed_has_value) {
base::Value::Dict sheets_policy;
sheets_policy.Set(kValue, static_cast<int>(ptr->max_sheets_allowed));
policies.Set(kSheets, std::move(sheets_policy));
}
base::Value::Dict color_policy;
if (ptr->allowed_color_modes)
color_policy.Set(kAllowedMode, static_cast<int>(ptr->allowed_color_modes));
if (ptr->default_color_mode != printing::mojom::ColorModeRestriction::kUnset)
color_policy.Set(kDefaultMode, static_cast<int>(ptr->default_color_mode));
if (!color_policy.empty())
policies.Set(kColor, std::move(color_policy));
base::Value::Dict duplex_policy;
if (ptr->allowed_duplex_modes)
duplex_policy.Set(kAllowedMode,
static_cast<int>(ptr->allowed_duplex_modes));
if (ptr->default_duplex_mode !=
printing::mojom::DuplexModeRestriction::kUnset)
duplex_policy.Set(kDefaultMode, static_cast<int>(ptr->default_duplex_mode));
if (!duplex_policy.empty())
policies.Set(kDuplex, std::move(duplex_policy));
base::Value::Dict pin_policy;
if (ptr->allowed_pin_modes != printing::mojom::PinModeRestriction::kUnset)
pin_policy.Set(kAllowedMode, static_cast<int>(ptr->allowed_pin_modes));
if (ptr->default_pin_mode != printing::mojom::PinModeRestriction::kUnset)
pin_policy.Set(kDefaultMode, static_cast<int>(ptr->default_pin_mode));
if (!pin_policy.empty())
policies.Set(kPin, std::move(pin_policy));
base::Value::Dict print_as_image_for_pdf_default_policy;
if (ptr->default_print_pdf_as_image !=
crosapi::mojom::Policies::OptionalBool::kUnset) {
print_as_image_for_pdf_default_policy.Set(
kDefaultMode, ptr->default_print_pdf_as_image ==
crosapi::mojom::Policies::OptionalBool::kTrue);
}
if (!print_as_image_for_pdf_default_policy.empty()) {
policies.Set(kPrintPdfAsImage,
std::move(print_as_image_for_pdf_default_policy));
}
return policies;
}
#else
base::Value::Dict GetPolicies(const PrefService& prefs) { … }
#endif
}
PrintPreviewHandler::PrintPreviewHandler() { … }
PrintPreviewHandler::~PrintPreviewHandler() = default;
void PrintPreviewHandler::RegisterMessages() { … }
void PrintPreviewHandler::OnJavascriptAllowed() { … }
void PrintPreviewHandler::OnJavascriptDisallowed() { … }
WebContents* PrintPreviewHandler::preview_web_contents() { … }
PrefService* PrintPreviewHandler::GetPrefs() { … }
void PrintPreviewHandler::ReadPrinterTypeDenyListFromPrefs() { … }
void PrintPreviewHandler::OnPrinterTypeDenyListReady(
const std::vector<mojom::PrinterType>& deny_list_types) { … }
PrintPreviewUI* PrintPreviewHandler::print_preview_ui() { … }
bool PrintPreviewHandler::ShouldReceiveRendererMessage(int request_id) { … }
std::string PrintPreviewHandler::GetCallbackId(int request_id) { … }
void PrintPreviewHandler::HandleGetPrinters(const base::Value::List& args) { … }
void PrintPreviewHandler::HandleGetPrinterCapabilities(
const base::Value::List& args) { … }
void PrintPreviewHandler::HandleGetPreview(const base::Value::List& args) { … }
void PrintPreviewHandler::HandleDoPrint(const base::Value::List& args) { … }
#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
void PrintPreviewHandler::OnVerdictByEnterprisePolicy(
UserActionBuckets user_action,
base::Value::Dict settings,
scoped_refptr<base::RefCountedMemory> data,
const std::string& callback_id,
bool allowed) { … }
void PrintPreviewHandler::OnHidePreviewDialog() { … }
#endif
void PrintPreviewHandler::FinishHandleDoPrint(
UserActionBuckets user_action,
base::Value::Dict settings,
scoped_refptr<base::RefCountedMemory> data,
const std::string& callback_id) { … }
void PrintPreviewHandler::HandleHidePreview(const base::Value::List& ) { … }
void PrintPreviewHandler::HandleCancelPendingPrintRequest(
const base::Value::List& ) { … }
void PrintPreviewHandler::HandleSaveAppState(const base::Value::List& args) { … }
#if BUILDFLAG(ENABLE_BASIC_PRINT_DIALOG)
void PrintPreviewHandler::HandleShowSystemDialog(
const base::Value::List& ) { … }
#endif
void PrintPreviewHandler::HandleClosePreviewDialog(
const base::Value::List& ) { … }
void PrintPreviewHandler::GetLocaleInformation(base::Value::Dict* settings) { … }
void PrintPreviewHandler::HandleGetInitialSettings(
const base::Value::List& args) { … }
void PrintPreviewHandler::SendInitialSettings(
const std::string& callback_id,
base::Value::Dict policies,
const std::string& default_printer) { … }
void PrintPreviewHandler::ClosePreviewDialog() { … }
void PrintPreviewHandler::SendPrinterCapabilities(
const std::string& callback_id,
base::Value::Dict settings_info) { … }
WebContents* PrintPreviewHandler::GetInitiator() { … }
const mojom::RequestPrintPreviewParams*
PrintPreviewHandler::GetRequestParams() { … }
void PrintPreviewHandler::OnPrintPreviewReady(int preview_uid, int request_id) { … }
void PrintPreviewHandler::OnPrintPreviewFailed(int request_id) { … }
void PrintPreviewHandler::OnInvalidPrinterSettings(int request_id) { … }
void PrintPreviewHandler::SendPrintPresetOptions(bool disable_scaling,
int copies,
mojom::DuplexMode duplex,
int request_id) { … }
void PrintPreviewHandler::SendPageCountReady(int page_count,
int fit_to_page_scaling,
int request_id) { … }
void PrintPreviewHandler::SendPageLayoutReady(
base::Value::Dict layout,
bool all_pages_have_custom_size,
bool all_pages_have_custom_orientation,
int request_id) { … }
void PrintPreviewHandler::SendPagePreviewReady(int page_index,
int preview_uid,
int preview_request_id) { … }
void PrintPreviewHandler::OnPrintPreviewCancelled(int request_id) { … }
void PrintPreviewHandler::OnPrintRequestCancelled() { … }
void PrintPreviewHandler::ClearInitiatorDetails() { … }
PrinterHandler* PrintPreviewHandler::GetPrinterHandler(
mojom::PrinterType printer_type) { … }
PdfPrinterHandler* PrintPreviewHandler::GetPdfPrinterHandler() { … }
void PrintPreviewHandler::OnAddedPrinters(mojom::PrinterType printer_type,
base::Value::List printers) { … }
void PrintPreviewHandler::OnGetPrintersDone(const std::string& callback_id,
mojom::PrinterType printer_type,
const base::TimeTicks& start_time) { … }
void PrintPreviewHandler::OnPrintResult(const std::string& callback_id,
const base::Value& error) { … }
void PrintPreviewHandler::BadMessageReceived() { … }
void PrintPreviewHandler::FileSelectedForTesting(const base::FilePath& path,
int index) { … }
void PrintPreviewHandler::SetPdfSavedClosureForTesting(
base::OnceClosure closure) { … }
void PrintPreviewHandler::HandleManagePrinters(const base::Value::List& args) { … }
}