chromium/chrome/browser/ui/webui/print_preview/print_preview_handler.cc

// Copyright 2012 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/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  // BUILDFLAG(IS_MAC)
#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) {}

// Dictionary Fields for Print Preview initial settings. Keep in sync with
// field names for print_preview.NativeInitialSettings in
// chrome/browser/resources/print_preview/native_layer.js
//
// Name of a dictionary field specifying whether to print automatically in
// kiosk mode. See http://crbug.com/31395.
const char kIsInKioskAutoPrintMode[] =;
// Dictionary field to indicate whether Chrome is running in forced app (app
// kiosk) mode. It's not the same as desktop Chrome kiosk (the one above).
const char kIsInAppKioskMode[] =;
// Name of a dictionary field holding the UI locale.
const char kUiLocale[] =;
// Name of a dictionary field holding the thousands delimiter according to the
// locale.
const char kThousandsDelimiter[] =;
// Name of a dictionary field holding the decimal delimiter according to the
// locale.
const char kDecimalDelimiter[] =;
// Name of a dictionary field holding the measurement system according to the
// locale.
const char kUnitType[] =;
// Name of a dictionary field holding the initiator title.
const char kDocumentTitle[] =;
// Name of a dictionary field holding the state of selection for document.
const char kDocumentHasSelection[] =;
// Name of a dictionary field holding saved print preview state
const char kAppState[] =;
// Name of a dictionary field holding the default destination selection rules.
const char kDefaultDestinationSelectionRules[] =;
// Name of a dictionary field holding policy values for printing settings.
const char kPolicies[] =;
// Name of a dictionary field holding policy allowed mode value for the setting.
const char kAllowedMode[] =;
// Name of a dictionary field holding policy default mode value for the setting.
const char kDefaultMode[] =;
// Name of a dictionary pref holding the policy value for the header/footer
// checkbox.
const char kHeaderFooter[] =;
// Name of a dictionary pref holding the policy value for the background
// graphics checkbox.
const char kCssBackground[] =;
// Name of a dictionary pref holding the policy value for the paper size
// setting.
const char kMediaSize[] =;
#if BUILDFLAG(IS_CHROMEOS)
// Name of a dictionary field holding policy value for the setting.
const char kValue[] = "value";
// Name of a dictionary pref holding the policy value for the sheets number.
const char kSheets[] = "sheets";
// Name of a dictionary pref holding the policy value for the color setting.
const char kColor[] = "color";
// Name of a dictionary pref holding the policy value for the duplex setting.
const char kDuplex[] = "duplex";
// Name of a dictionary pref holding the policy value for the pin setting.
const char kPin[] = "pin";
#endif  // BUILDFLAG(IS_CHROMEOS)
// Name of a dictionary field indicating whether the 'Save to PDF' destination
// is disabled.
const char kPdfPrinterDisabled[] =;
// Name of a dictionary field indicating whether the destinations are managed by
// the PrinterTypeDenyList enterprise policy.
const char kDestinationsManaged[] =;
#if BUILDFLAG(IS_CHROMEOS)
// Name of a dictionary field indicating whether the user's Drive directory is
// mounted.
const char kIsDriveMounted[] = "isDriveMounted";
#endif  // BUILDFLAG(IS_CHROMEOS)
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
// Name of a dictionary pref holding the policy value for whether the
// "Print as image" option should be available to the user in the Print Preview
// for a PDF job.
const char kPrintPdfAsImageAvailability[] = "printPdfAsImageAvailability";
#endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
// Name of dictionary pref holding policy value for whether the
// "Print as image" option should default to set in Print Preview for
// a PDF job.
const char kPrintPdfAsImage[] =;

// Gets the print job settings dictionary from |json_str|. Assumes the Print
// Preview WebUI does not send over invalid data.
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  // BUILDFLAG(IS_CHROMEOS)

}  // namespace

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  // BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)

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& /*args*/) {}

void PrintPreviewHandler::HandleCancelPendingPrintRequest(
    const base::Value::List& /*args*/) {}

void PrintPreviewHandler::HandleSaveAppState(const base::Value::List& args) {}

#if BUILDFLAG(ENABLE_BASIC_PRINT_DIALOG)
void PrintPreviewHandler::HandleShowSystemDialog(
    const base::Value::List& /*args*/) {}
#endif

void PrintPreviewHandler::HandleClosePreviewDialog(
    const base::Value::List& /*args*/) {}

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) {}

}  // namespace printing