// 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/printing/print_backend_service_manager.h"

#include <memory>
#include <string>
#include <utility>

#include "base/bind.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/logging.h"
#include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/services/printing/public/mojom/print_backend_service.mojom.h"
#include "components/crash/core/common/crash_keys.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/service_process_host.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "printing/backend/print_backend.h"
#include "printing/printing_features.h"

#if BUILDFLAG(IS_WIN)
#include "base/win/win_util.h"
#include "chrome/browser/printing/printer_xml_parser_impl.h"
#include "chrome/services/printing/public/mojom/printer_xml_parser.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "printing/backend/win_helper.h"
#include "printing/printed_page_win.h"
#include "ui/views/win/hwnd_util.h"
#endif

namespace printing {

namespace {

// Histogram name for capturing if any printer drivers were encountered that
// required fallback to workaround an access-denied error.  Determining if this
// happens in the wild would be the impetus to pursue further efforts to
// identify and possibly better rectify such cases.
constexpr char kPrintBackendRequiresElevatedPrivilegeHistogramName[] =
    "Printing.PrintBackend.DriversRequiringElevatedPrivilegeEncountered";

// For fetching remote IDs when there is no printer name.
constexpr char kEmptyPrinterName[] = "";

PrintBackendServiceManager* g_print_backend_service_manager_singleton = nullptr;

size_t GetClientsCountForRemoteId(
    const PrintBackendServiceManager::PrintClientsMap& clients,
    const PrintBackendServiceManager::RemoteId& remote_id) {
  auto iter = clients.find(remote_id);
  if (iter != clients.end()) {
    DCHECK(!iter->second.empty());
    return iter->second.size();
  }
  return 0;
}

#if BUILDFLAG(IS_WIN)
// TODO(crbug.com/809738):  Update for other platforms as they are made able
// to support modal dialogs from OOP.
uint32_t NativeViewToUint(gfx::NativeView view) {
  return base::win::HandleToUint32(views::HWNDForNativeView(view));
}
#endif

}  // namespace

PrintBackendServiceManager::CallbackContext::CallbackContext() = default;

PrintBackendServiceManager::CallbackContext::CallbackContext(
    PrintBackendServiceManager::CallbackContext&& other) noexcept = default;

PrintBackendServiceManager::CallbackContext::~CallbackContext() = default;

PrintBackendServiceManager::PrintBackendServiceManager() = default;

PrintBackendServiceManager::~PrintBackendServiceManager() = default;

// static
void PrintBackendServiceManager::LogCallToRemote(
    base::StringPiece name,
    const CallbackContext& context) {
  DVLOG(1) << "Sending " << name << " on remote `" << context.remote_id
           << "`, saved callback ID of " << context.saved_callback_id;
}

// static
void PrintBackendServiceManager::LogCallbackFromRemote(
    base::StringPiece name,
    const CallbackContext& context) {
  DVLOG(1) << name << " completed for remote `" << context.remote_id
           << "` saved callback ID " << context.saved_callback_id;
}

void PrintBackendServiceManager::SetCrashKeys(const std::string& printer_name) {
  if (sandboxed_service_remote_for_test_)
    return;

  // TODO(crbug.com/1227561)  Remove local call for driver info, don't want
  // any residual accesses left into the printer drivers from the browser
  // process.
  base::ScopedAllowBlocking allow_blocking;
  scoped_refptr<PrintBackend> print_backend =
      PrintBackend::CreateInstance(g_browser_process->GetApplicationLocale());
  crash_keys_ = std::make_unique<crash_keys::ScopedPrinterInfo>(
      print_backend->GetPrinterDriverInfo(printer_name));
}

uint32_t PrintBackendServiceManager::RegisterQueryClient() {
  return *RegisterClient(ClientType::kQuery, kEmptyPrinterName);
}

absl::optional<uint32_t>
PrintBackendServiceManager::RegisterQueryWithUiClient() {
  return RegisterClient(ClientType::kQueryWithUi, kEmptyPrinterName);
}
uint32_t PrintBackendServiceManager::RegisterPrintDocumentClient(
    const std::string& printer_name) {
  DCHECK_NE(printer_name, kEmptyPrinterName);
  return *RegisterClient(ClientType::kPrintDocument, printer_name);
}

void PrintBackendServiceManager::UnregisterClient(uint32_t id) {
  // Determine which client type has this ID, and remove it once found.
  absl::optional<ClientType> client_type;
  RemoteId remote_id = GetRemoteIdForPrinterName(kEmptyPrinterName);
  if (query_clients_.erase(id) != 0) {
    client_type = ClientType::kQuery;
  } else if (query_with_ui_clients_.erase(id) != 0) {
    client_type = ClientType::kQueryWithUi;
  } else {
    for (auto& item : print_document_clients_) {
      ClientsSet& clients = item.second;
      if (clients.erase(id) != 0) {
        client_type = ClientType::kPrintDocument;
        remote_id = item.first;
        if (clients.empty())
          print_document_clients_.erase(item);
        break;
      }
    }
  }
  if (!client_type.has_value()) {
    DVLOG(1) << "Unknown client ID " << id
             << ", is client being unregistered multiple times?";
    return;
  }
  VLOG(1) << "Unregistering client with ID " << id
          << " from print backend service.";

  absl::optional<base::TimeDelta> new_timeout =
      DetermineIdleTimeoutUpdateOnUnregisteredClient(client_type.value(),
                                                     remote_id);
  if (new_timeout.has_value())
    UpdateServiceIdleTimeoutByRemoteId(remote_id, new_timeout.value());

#if BUILDFLAG(IS_WIN)
  if (base::FeatureList::IsEnabled(features::kReadPrinterCapabilitiesWithXps) &&
      query_clients_.empty()) {
    xml_parser_.reset();
  }
#endif  // BUILDFLAG(IS_WIN)
}

void PrintBackendServiceManager::EnumeratePrinters(
    mojom::PrintBackendService::EnumeratePrintersCallback callback) {
  CallbackContext context;
  auto& service = GetServiceAndCallbackContext(kEmptyPrinterName,
                                               ClientType::kQuery, context);

  SaveCallback(GetRemoteSavedEnumeratePrintersCallbacks(context.is_sandboxed),
               context.remote_id, context.saved_callback_id,
               std::move(callback));

  LogCallToRemote("EnumeratePrinters", context);
  service->EnumeratePrinters(
      base::BindOnce(&PrintBackendServiceManager::OnDidEnumeratePrinters,
                     base::Unretained(this), std::move(context)));
}

void PrintBackendServiceManager::FetchCapabilities(
    const std::string& printer_name,
    mojom::PrintBackendService::FetchCapabilitiesCallback callback) {
  CallbackContext context;
  auto& service =
      GetServiceAndCallbackContext(printer_name, ClientType::kQuery, context);

  SaveCallback(GetRemoteSavedFetchCapabilitiesCallbacks(context.is_sandboxed),
               context.remote_id, context.saved_callback_id,
               std::move(callback));

  SetCrashKeys(printer_name);

  LogCallToRemote("FetchCapabilities", context);
  service->FetchCapabilities(
      printer_name,
      base::BindOnce(&PrintBackendServiceManager::OnDidFetchCapabilities,
                     base::Unretained(this), std::move(context)));
}

void PrintBackendServiceManager::GetDefaultPrinterName(
    mojom::PrintBackendService::GetDefaultPrinterNameCallback callback) {
  CallbackContext context;
  auto& service = GetServiceAndCallbackContext(kEmptyPrinterName,
                                               ClientType::kQuery, context);

  SaveCallback(
      GetRemoteSavedGetDefaultPrinterNameCallbacks(context.is_sandboxed),
      context.remote_id, context.saved_callback_id, std::move(callback));

  LogCallToRemote("GetDefaultPrinterName", context);
  service->GetDefaultPrinterName(
      base::BindOnce(&PrintBackendServiceManager::OnDidGetDefaultPrinterName,
                     base::Unretained(this), std::move(context)));
}

void PrintBackendServiceManager::GetPrinterSemanticCapsAndDefaults(
    const std::string& printer_name,
    mojom::PrintBackendService::GetPrinterSemanticCapsAndDefaultsCallback
        callback) {
  CallbackContext context;
  auto& service =
      GetServiceAndCallbackContext(printer_name, ClientType::kQuery, context);

  SaveCallback(GetRemoteSavedGetPrinterSemanticCapsAndDefaultsCallbacks(
                   context.is_sandboxed),
               context.remote_id, context.saved_callback_id,
               std::move(callback));

  SetCrashKeys(printer_name);

  LogCallToRemote("GetPrinterSemanticCapsAndDefaults", context);
  service->GetPrinterSemanticCapsAndDefaults(
      printer_name,
      base::BindOnce(
          &PrintBackendServiceManager::OnDidGetPrinterSemanticCapsAndDefaults,
          base::Unretained(this), std::move(context)));
}

void PrintBackendServiceManager::UseDefaultSettings(
    const std::string& printer_name,
    mojom::PrintBackendService::UseDefaultSettingsCallback callback) {
  // Even though this call does not require a UI, it is used exclusively as
  // part of preparation for system print.  It is called immediately before a
  // call to `AskDefaultSettings()`.  Since that call requires `kQueryWithUi`,
  // it will behave better to ensure this uses the same type to reuse the same
  // process.
  CallbackContext context;
  auto& service = GetServiceAndCallbackContext(
      printer_name, ClientType::kQueryWithUi, context);

  SaveCallback(GetRemoteSavedUseDefaultSettingsCallbacks(context.is_sandboxed),
               context.remote_id, context.saved_callback_id,
               std::move(callback));

  SetCrashKeys(printer_name);

  LogCallToRemote("UseDefaultSettings", context);
  service->UseDefaultSettings(
      base::BindOnce(&PrintBackendServiceManager::OnDidUseDefaultSettings,
                     base::Unretained(this), std::move(context)));
}

#if BUILDFLAG(IS_WIN)
void PrintBackendServiceManager::AskUserForSettings(
    const std::string& printer_name,
    gfx::NativeView parent_view,
    int max_pages,
    bool has_selection,
    bool is_scripted,
    mojom::PrintBackendService::AskUserForSettingsCallback callback) {
  CallbackContext context;
  auto& service = GetServiceAndCallbackContext(
      printer_name, ClientType::kQueryWithUi, context);

  SaveCallback(GetRemoteSavedAskUserForSettingsCallbacks(context.is_sandboxed),
               context.remote_id, context.saved_callback_id,
               std::move(callback));

  SetCrashKeys(printer_name);

  LogCallToRemote("AskUserForSettings", context);
  service->AskUserForSettings(
      NativeViewToUint(parent_view), max_pages, has_selection, is_scripted,
      base::BindOnce(&PrintBackendServiceManager::OnDidAskUserForSettings,
                     base::Unretained(this), std::move(context)));
}
#endif  // BUILDFLAG(IS_WIN)

void PrintBackendServiceManager::UpdatePrintSettings(
    const std::string& printer_name,
    base::Value::Dict job_settings,
    mojom::PrintBackendService::UpdatePrintSettingsCallback callback) {
  CallbackContext context;
  auto& service =
      GetServiceAndCallbackContext(printer_name, ClientType::kQuery, context);

  SaveCallback(GetRemoteSavedUpdatePrintSettingsCallbacks(context.is_sandboxed),
               context.remote_id, context.saved_callback_id,
               std::move(callback));

  SetCrashKeys(printer_name);

  LogCallToRemote("UpdatePrintSettings", context);
  service->UpdatePrintSettings(
      std::move(job_settings),
      base::BindOnce(&PrintBackendServiceManager::OnDidUpdatePrintSettings,
                     base::Unretained(this), std::move(context)));
}

void PrintBackendServiceManager::StartPrinting(
    const std::string& printer_name,
    int document_cookie,
    const std::u16string& document_name,
    mojom::PrintTargetType target_type,
    const PrintSettings& settings,
    mojom::PrintBackendService::StartPrintingCallback callback) {
  CallbackContext context;
  auto& service = GetServiceAndCallbackContext(
      printer_name, ClientType::kPrintDocument, context);

  SaveCallback(GetRemoteSavedStartPrintingCallbacks(context.is_sandboxed),
               context.remote_id, context.saved_callback_id,
               std::move(callback));

  SetCrashKeys(printer_name);

  LogCallToRemote("StartPrinting", context);
  service->StartPrinting(
      document_cookie, document_name, target_type, settings,
      base::BindOnce(&PrintBackendServiceManager::OnDidStartPrinting,
                     base::Unretained(this), std::move(context)));
}

#if BUILDFLAG(IS_WIN)
void PrintBackendServiceManager::RenderPrintedPage(
    const std::string& printer_name,
    int document_cookie,
    const PrintedPage& page,
    mojom::MetafileDataType page_data_type,
    base::ReadOnlySharedMemoryRegion serialized_page_data,
    mojom::PrintBackendService::RenderPrintedPageCallback callback) {
  CallbackContext context;
  auto& service = GetServiceAndCallbackContext(
      printer_name, ClientType::kPrintDocument, context);

  SaveCallback(GetRemoteSavedRenderPrintedPageCallbacks(context.is_sandboxed),
               context.remote_id, context.saved_callback_id,
               std::move(callback));

  SetCrashKeys(printer_name);

  // Page numbers are 0-based for the printing context.
  const uint32_t page_index = page.page_number() - 1;

  LogCallToRemote("RenderPrintedPage", context);
  service->RenderPrintedPage(
      document_cookie, page_index, page_data_type,
      std::move(serialized_page_data), page.page_size(),
      page.page_content_rect(), page.shrink_factor(),
      base::BindOnce(&PrintBackendServiceManager::OnDidRenderPrintedPage,
                     base::Unretained(this), std::move(context)));
}
#endif  // BUILDFLAG(IS_WIN)

void PrintBackendServiceManager::RenderPrintedDocument(
    const std::string& printer_name,
    int document_cookie,
    uint32_t page_count,
    mojom::MetafileDataType data_type,
    base::ReadOnlySharedMemoryRegion serialized_data,
    mojom::PrintBackendService::RenderPrintedDocumentCallback callback) {
  CallbackContext context;
  auto& service = GetServiceAndCallbackContext(
      printer_name, ClientType::kPrintDocument, context);

  SaveCallback(
      GetRemoteSavedRenderPrintedDocumentCallbacks(context.is_sandboxed),
      context.remote_id, context.saved_callback_id, std::move(callback));

  SetCrashKeys(printer_name);

  LogCallToRemote("RenderPrintedDocument", context);
  service->RenderPrintedDocument(
      document_cookie, page_count, data_type, std::move(serialized_data),
      base::BindOnce(&PrintBackendServiceManager::OnDidRenderPrintedDocument,
                     base::Unretained(this), std::move(context)));
}

void PrintBackendServiceManager::DocumentDone(
    const std::string& printer_name,
    int document_cookie,
    mojom::PrintBackendService::DocumentDoneCallback callback) {
  CallbackContext context;
  auto& service = GetServiceAndCallbackContext(
      printer_name, ClientType::kPrintDocument, context);

  SaveCallback(GetRemoteSavedDocumentDoneCallbacks(context.is_sandboxed),
               context.remote_id, context.saved_callback_id,
               std::move(callback));

  SetCrashKeys(printer_name);

  LogCallToRemote("DocumentDone", context);
  service->DocumentDone(
      document_cookie,
      base::BindOnce(&PrintBackendServiceManager::OnDidDocumentDone,
                     base::Unretained(this), std::move(context)));
}

void PrintBackendServiceManager::Cancel(
    const std::string& printer_name,
    int document_cookie,
    mojom::PrintBackendService::CancelCallback callback) {
  CallbackContext context;
  auto& service = GetServiceAndCallbackContext(
      printer_name, ClientType::kPrintDocument, context);

  SaveCallback(GetRemoteSavedCancelCallbacks(context.is_sandboxed),
               context.remote_id, context.saved_callback_id,
               std::move(callback));

  SetCrashKeys(printer_name);

  LogCallToRemote("Cancel", context);
  service->Cancel(document_cookie,
                  base::BindOnce(&PrintBackendServiceManager::OnDidCancel,
                                 base::Unretained(this), std::move(context)));
}

bool PrintBackendServiceManager::PrinterDriverFoundToRequireElevatedPrivilege(
    const std::string& printer_name) const {
  return drivers_requiring_elevated_privilege_.contains(printer_name);
}

void PrintBackendServiceManager::
    SetPrinterDriverFoundToRequireElevatedPrivilege(
        const std::string& printer_name) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  VLOG(1) << "Destination '" << printer_name
          << "' requires elevated privileges.";
  if (drivers_requiring_elevated_privilege_.emplace(printer_name).second &&
      drivers_requiring_elevated_privilege_.size() == 1) {
    // First time we've detected a problem for any driver.
    base::UmaHistogramBoolean(
        kPrintBackendRequiresElevatedPrivilegeHistogramName, /*sample=*/true);
  }
}

void PrintBackendServiceManager::SetServiceForTesting(
    mojo::Remote<mojom::PrintBackendService>* remote) {
  sandboxed_service_remote_for_test_ = remote;
  sandboxed_service_remote_for_test_->set_disconnect_handler(base::BindOnce(
      &PrintBackendServiceManager::OnRemoteDisconnected, base::Unretained(this),
      /*sandboxed=*/true,
      GetRemoteIdForPrinterName(/*printer_name=*/std::string())));
}

void PrintBackendServiceManager::SetServiceForFallbackTesting(
    mojo::Remote<mojom::PrintBackendService>* remote) {
  unsandboxed_service_remote_for_test_ = remote;
  unsandboxed_service_remote_for_test_->set_disconnect_handler(base::BindOnce(
      &PrintBackendServiceManager::OnRemoteDisconnected, base::Unretained(this),
      /*sandboxed=*/false,
      GetRemoteIdForPrinterName(/*printer_name=*/std::string())));
}

// static
PrintBackendServiceManager& PrintBackendServiceManager::GetInstance() {
  if (!g_print_backend_service_manager_singleton) {
    g_print_backend_service_manager_singleton =
        new PrintBackendServiceManager();
  }
  return *g_print_backend_service_manager_singleton;
}

// static
void PrintBackendServiceManager::ResetForTesting() {
  if (g_print_backend_service_manager_singleton) {
    delete g_print_backend_service_manager_singleton;
    g_print_backend_service_manager_singleton = nullptr;
  }
}

PrintBackendServiceManager::RemoteId
PrintBackendServiceManager::GetRemoteIdForPrinterName(
    const std::string& printer_name) {
#if BUILDFLAG(IS_WIN)
  if (!sandboxed_service_remote_for_test_) {
    // Windows drivers are not thread safe.  Use a process per driver to prevent
    // bad interactions when interfacing to multiple drivers in parallel.
    // https://crbug.com/957242
    auto iter = remote_id_map_.find(printer_name);
    if (iter != remote_id_map_.end()) {
      return iter->second;
    }

    // No remote yet for this printer so make one.  RemoteId is only used within
    // browse process management code, so a simple incrementing sequence is
    // sufficient.
    static uint32_t id_sequence = 0;
    return remote_id_map_.insert({printer_name, RemoteId(++id_sequence)})
        .first->second;
  }
#endif

  // Non-Windows platforms and the testing environment always just use one
  // instance for all printers.
  return RemoteId(1);
}

absl::optional<uint32_t> PrintBackendServiceManager::RegisterClient(
    ClientType client_type,
    const std::string& printer_name) {
  uint32_t client_id = ++last_client_id_;
  RemoteId remote_id = GetRemoteIdForPrinterName(printer_name);

  VLOG(1) << "Registering a client with ID " << client_id
          << " for print backend service.";
  switch (client_type) {
    case ClientType::kQuery:
      query_clients_.insert(client_id);
      break;
    case ClientType::kQueryWithUi:
#if !BUILDFLAG(IS_LINUX)
      if (!query_with_ui_clients_.empty())
        return absl::nullopt;
#endif
      query_with_ui_clients_.insert(client_id);
      break;
    case ClientType::kPrintDocument:
      print_document_clients_[remote_id].insert(client_id);
      break;
  }

  // A new client registration is a signal of impending activity to a print
  // backend service.  Performance can be improved if we ensure that an initial
  // service is ready for when the first Mojo call should happen shortly after
  // this registration.
  // It is possible that there might have been prior clients registered that
  // persisted for a long time (e.g., a tab with a Print Preview left open
  // indefinitely).  We use a long timeout against idleness for that scenario,
  // so we want to perform this optimization check every time regardless of
  // number of clients registered.
  // System print is a special case because it can display a system dialog and
  // is window modal.  In this scenario we do not want the print backend to
  // self-terminate even if the user is idle for a long period of time.
  auto iter = sandboxed_remotes_bundles_.find(remote_id);
  if (iter == sandboxed_remotes_bundles_.end()) {
    // Service not already available, so launch it now so that it will be
    // ready by the time the client gets to point of invoking a Mojo call.
    bool is_sandboxed;
    GetService(printer_name, client_type, &is_sandboxed);
  } else {
    // Service already existed, possibly was recently marked for being reset
    // with a short timeout or is already in use for other client types.
    // Determine if any adjustment to the timeout is actually necessary.
    absl::optional<base::TimeDelta> new_timeout =
        DetermineIdleTimeoutUpdateOnRegisteredClient(client_type, remote_id);
    if (new_timeout.has_value())
      UpdateServiceIdleTimeoutByRemoteId(remote_id, new_timeout.value());
  }

  return client_id;
}

size_t PrintBackendServiceManager::GetClientsRegisteredCount() const {
  size_t clients_count = query_clients_.size() + query_with_ui_clients_.size();
  for (auto& item : print_document_clients_)
    clients_count += item.second.size();
  return clients_count;
}

#if BUILDFLAG(IS_WIN)
bool PrintBackendServiceManager::PrinterDriverKnownToRequireElevatedPrivilege(
    const std::string& printer_name,
    ClientType client_type) {
  // Any Windows printer driver which causes a UI dialog to be displayed does
  // not work if printing is started from within a sandboxed environment.
  // crbug.com/1243873
  switch (client_type) {
    case ClientType::kQuery:
      return false;
    case ClientType::kQueryWithUi:
      // Guaranteed to display the system print dialog.
      return true;
    case ClientType::kPrintDocument:
      // Drivers with a print port that results in saving to a file will cause
      // a system dialog to be displayed.
      return DoesDriverDisplayFileDialogForPrinting(printer_name);
  }
}
#endif  // BUILDFLAG(IS_WIN)

const mojo::Remote<mojom::PrintBackendService>&
PrintBackendServiceManager::GetService(const std::string& printer_name,
                                       ClientType client_type,
                                       bool* is_sandboxed) {
  // Determine if sandboxing is appropriate.  This might be already known for
  // certain drivers/configurations, or learned during runtime.
  bool should_sandbox =
      features::kEnableOopPrintDriversSandbox.Get() &&
      !PrinterDriverFoundToRequireElevatedPrivilege(printer_name);
#if BUILDFLAG(IS_WIN)
  if (should_sandbox) {
    should_sandbox = !PrinterDriverKnownToRequireElevatedPrivilege(printer_name,
                                                                   client_type);
  }
#endif
  *is_sandboxed = should_sandbox;

  if (sandboxed_service_remote_for_test_) {
    // The presence of a sandboxed remote for testing signals a testing
    // environment.  If no unsandboxed test service was provided for fallback
    // processing then use the sandboxed one for that as well.
    if (!should_sandbox && unsandboxed_service_remote_for_test_)
      return *unsandboxed_service_remote_for_test_;

    return *sandboxed_service_remote_for_test_;
  }

  // Performance is improved if a service is launched ahead of the time it will
  // be needed by client callers.
  DCHECK_GT(GetClientsRegisteredCount(), 0u);

  if (should_sandbox) {
    // On the first print that will try to use sandboxed service, make note that
    // so far no drivers have been discovered to require fallback beyond any
    // predetermined known cases.
    static bool first_sandboxed_print = true;
    if (first_sandboxed_print) {
      first_sandboxed_print = false;
      base::UmaHistogramBoolean(
          kPrintBackendRequiresElevatedPrivilegeHistogramName,
          /*sample=*/false);
    }
  }

  RemoteId remote_id = GetRemoteIdForPrinterName(printer_name);
  if (should_sandbox) {
    return GetServiceFromBundle(remote_id, client_type, /*sandboxed=*/true,
                                sandboxed_remotes_bundles_);
  }
  return GetServiceFromBundle(remote_id, client_type, /*sandboxed=*/false,
                              unsandboxed_remotes_bundles_);
}

template <class T>
mojo::Remote<mojom::PrintBackendService>&
PrintBackendServiceManager::GetServiceFromBundle(
    const RemoteId& remote_id,
    ClientType client_type,
    bool sandboxed,
    RemotesBundleMap<T>& bundle_map) {
  auto iter = bundle_map.find(remote_id);
  if (iter == bundle_map.end()) {
    // First time for this `remote_id`.
    auto result =
        bundle_map.emplace(remote_id, std::make_unique<RemotesBundle<T>>());
    iter = result.first;
  }

  RemotesBundle<T>* bundle = iter->second.get();
  mojo::Remote<mojom::PrintBackendService>& service = bundle->service;
  if (!service) {
    VLOG(1) << "Launching print backend "
            << (sandboxed ? "sandboxed" : "unsandboxed") << " for `"
            << remote_id << "`";

    mojo::Remote<T>& host = bundle->host;
    content::ServiceProcessHost::Launch(
        host.BindNewPipeAndPassReceiver(),
        content::ServiceProcessHost::Options()
            .WithDisplayName(IDS_UTILITY_PROCESS_PRINT_BACKEND_SERVICE_NAME)
            .Pass());
    host->BindBackend(service.BindNewPipeAndPassReceiver());

    // Ensure that if the interface is ever disconnected (e.g. the service
    // process crashes) then we will drop our handle to the remote.
    // Safe to use base::Unretained(this) since `this` is a global singleton
    // which never goes away.
    service.set_disconnect_handler(
        base::BindOnce(&PrintBackendServiceManager::OnRemoteDisconnected,
                       base::Unretained(this), sandboxed, remote_id));

    // We may want to have the service terminated when idle.
    SetServiceIdleHandler(service, sandboxed, remote_id,
                          GetClientTypeIdleTimeout(client_type));
#if BUILDFLAG(IS_WIN)
    // Initialize the new service for the desired locale. Bind
    // PrintBackendService with a Remote that allows pass-through requests to an
    // XML parser.
    mojo::PendingRemote<mojom::PrinterXmlParser> remote;
    if (base::FeatureList::IsEnabled(
            features::kReadPrinterCapabilitiesWithXps)) {
      if (!xml_parser_)
        xml_parser_ = std::make_unique<PrinterXmlParserImpl>();
      remote = xml_parser_->GetRemote();
    }
    service->Init(g_browser_process->GetApplicationLocale(), std::move(remote));
#else
    // Initialize the new service for the desired locale.
    service->Init(g_browser_process->GetApplicationLocale());
#endif  // BUILDFLAG(IS_WIN)
  }

  return service;
}

// static
constexpr base::TimeDelta PrintBackendServiceManager::GetClientTypeIdleTimeout(
    ClientType client_type) {
  switch (client_type) {
    case ClientType::kQuery:
      // Want a long timeout so that the service is available across typical
      // user interactions but will get reclaimed should the user leave it
      // unused indefinitely.  E.g., a Print Preview left open in a tab while
      // user has moved on to other tabs.
      return kClientsRegisteredResetOnIdleTimeout;

    case ClientType::kQueryWithUi:
      // Want the service to remain indefinitely, since this case supports a
      // window-modal system dialog being invoked from the service.
      return base::TimeDelta::Max();

    case ClientType::kPrintDocument:
      // Some print jobs can take a very long time to print.  Choosing some
      // threshold for reclaiming is hard to make and still have the effect
      // of service reclamation meaningful.  Err towards not accidentally
      // terminating an in-progress print job and let the service remain open
      // indefinitely, instead relying upon the registered clients mechanism
      // to reinstate a short timeout once a print job has completed.
      // For Windows there is the additional case where the driver might need
      // to display a file save system dialog (e.g., if the driver sends to
      // port FILE:), which is another window-modal system dialog invoked from
      // the service for which we would want to wait indefinitely.
      return base::TimeDelta::Max();
  }
}

absl::optional<base::TimeDelta>
PrintBackendServiceManager::DetermineIdleTimeoutUpdateOnRegisteredClient(
    ClientType registered_client_type,
    const RemoteId& remote_id) const {
  switch (registered_client_type) {
    case ClientType::kQuery:
      DCHECK(!query_clients_.empty());

      // Other query types have longer timeouts, so no need to update if
      // any of them have clients.
      if (!query_with_ui_clients_.empty() ||
          GetClientsCountForRemoteId(print_document_clients_, remote_id) > 0) {
        return absl::nullopt;
      }

      if (query_clients_.size() > 1)
        return absl::nullopt;

      // First client of type and no others will need an update.
      break;

    case ClientType::kQueryWithUi:
#if BUILDFLAG(IS_LINUX)
      // No need to update if there were other query with UI clients.
      if (query_with_ui_clients_.size() > 1)
        return absl::nullopt;
#else
      // A modal system dialog, of which there should only ever be at most one
      // of these.
      DCHECK_EQ(query_with_ui_clients_.size(), 1u);
#endif

      // This is the longest timeout.  No need to update if there is a similarly
      // long timeout due to a printing client.
      if (GetClientsCountForRemoteId(print_document_clients_, remote_id) > 0)
        return absl::nullopt;
      break;

    case ClientType::kPrintDocument:
      size_t clients_count =
          GetClientsCountForRemoteId(print_document_clients_, remote_id);
      DCHECK_GT(clients_count, 0u);

      // No need to update if there were other printing clients for same remote
      // ID.
      if (clients_count > 1)
        return absl::nullopt;

      // This is the longest timeout.  No need to update if there is a similarly
      // long timeout due to query with UI.
      if (!query_with_ui_clients_.empty())
        return absl::nullopt;
      break;
  }

  return GetClientTypeIdleTimeout(registered_client_type);
}

absl::optional<base::TimeDelta>
PrintBackendServiceManager::DetermineIdleTimeoutUpdateOnUnregisteredClient(
    ClientType unregistered_client_type,
    const RemoteId& remote_id) const {
  switch (unregistered_client_type) {
    case ClientType::kQuery:
      // Other query types have longer timeouts, so no need to update if
      // any of them have clients.
      if (!query_with_ui_clients_.empty() ||
          GetClientsCountForRemoteId(print_document_clients_, remote_id) > 0) {
        return absl::nullopt;
      }

      if (!query_clients_.empty())
        return absl::nullopt;

      // No remaining clients, can switch to short timeout for quick
      // reclamation.
      return kNoClientsRegisteredResetOnIdleTimeout;

    case ClientType::kQueryWithUi:
#if BUILDFLAG(IS_LINUX)
      // No need to update if there were other query with UI clients.
      if (!query_with_ui_clients_.empty())
        return absl::nullopt;
#else
      // A modal system dialog, of which there should only ever be at most one
      // of these. If one was dropped, it should now be empty.
      DCHECK(query_with_ui_clients_.empty());
#endif

      // This is the longest timeout, so no need to update if there is a
      // printing client for this `remote_id`.
      if (GetClientsCountForRemoteId(print_document_clients_, remote_id) > 0)
        return absl::nullopt;

      // New timeout depends upon existence of other queries.
      return query_clients_.empty() ? kNoClientsRegisteredResetOnIdleTimeout
                                    : kClientsRegisteredResetOnIdleTimeout;

    case ClientType::kPrintDocument:
      // No need to update if there were other printing clients for same remote
      // ID.
      if (GetClientsCountForRemoteId(print_document_clients_, remote_id) > 0)
        return absl::nullopt;

      // This is the longest timeout, so no need to update if there is still a
      // query with UI.
      if (!query_with_ui_clients_.empty())
        return absl::nullopt;

      // New timeout depends upon existence of other queries.
      return query_clients_.empty() ? kNoClientsRegisteredResetOnIdleTimeout
                                    : kClientsRegisteredResetOnIdleTimeout;
  }
}

void PrintBackendServiceManager::SetServiceIdleHandler(
    mojo::Remote<printing::mojom::PrintBackendService>& service,
    bool sandboxed,
    const RemoteId& remote_id,
    const base::TimeDelta& timeout) {
  DVLOG(1) << "Updating idle timeout for "
           << (sandboxed ? "sandboxed" : "unsandboxed")
           << " print backend service id `" << remote_id << "` to " << timeout;
  service.set_idle_handler(
      kNoClientsRegisteredResetOnIdleTimeout,
      base::BindRepeating(&PrintBackendServiceManager::OnIdleTimeout,
                          base::Unretained(this), sandboxed, remote_id));

  // TODO(crbug.com/1225111)  Make a superfluous call to the service, just to
  // cause an IPC that will in turn make the adjusted timeout value actually
  // take effect.
  service->Poke();
}

void PrintBackendServiceManager::UpdateServiceIdleTimeoutByRemoteId(
    const RemoteId& remote_id,
    const base::TimeDelta& timeout) {
  auto sandboxed_iter = sandboxed_remotes_bundles_.find(remote_id);
  if (sandboxed_iter != sandboxed_remotes_bundles_.end()) {
    RemotesBundle<mojom::SandboxedPrintBackendHost>* bundle =
        sandboxed_iter->second.get();
    SetServiceIdleHandler(bundle->service, /*sandboxed=*/true, remote_id,
                          timeout);
  }
  auto unsandboxed_iter = unsandboxed_remotes_bundles_.find(remote_id);
  if (unsandboxed_iter != unsandboxed_remotes_bundles_.end()) {
    RemotesBundle<mojom::UnsandboxedPrintBackendHost>* bundle =
        unsandboxed_iter->second.get();
    SetServiceIdleHandler(bundle->service, /*sandboxed=*/false, remote_id,
                          timeout);
  }
}

void PrintBackendServiceManager::OnIdleTimeout(bool sandboxed,
                                               const RemoteId& remote_id) {
  DVLOG(1) << "Print Backend service idle timeout for "
           << (sandboxed ? "sandboxed" : "unsandboxed") << " remote id `"
           << remote_id << "`";
  if (sandboxed) {
    sandboxed_remotes_bundles_.erase(remote_id);
  } else {
    unsandboxed_remotes_bundles_.erase(remote_id);
  }
}

void PrintBackendServiceManager::OnRemoteDisconnected(
    bool sandboxed,
    const RemoteId& remote_id) {
  DVLOG(1) << "Print Backend service disconnected for "
           << (sandboxed ? "sandboxed" : "unsandboxed") << " remote id `"
           << remote_id << "`";
  if (sandboxed) {
    sandboxed_remotes_bundles_.erase(remote_id);
  } else {
    unsandboxed_remotes_bundles_.erase(remote_id);
  }
  RunSavedCallbacksStructResult(
      GetRemoteSavedEnumeratePrintersCallbacks(sandboxed), remote_id,
      mojom::PrinterListResult::NewResultCode(mojom::ResultCode::kFailed));
  RunSavedCallbacksStructResult(
      GetRemoteSavedFetchCapabilitiesCallbacks(sandboxed), remote_id,
      mojom::PrinterCapsAndInfoResult::NewResultCode(
          mojom::ResultCode::kFailed));
  RunSavedCallbacksStructResult(
      GetRemoteSavedGetDefaultPrinterNameCallbacks(sandboxed), remote_id,
      mojom::DefaultPrinterNameResult::NewResultCode(
          mojom::ResultCode::kFailed));
  RunSavedCallbacksStructResult(
      GetRemoteSavedGetPrinterSemanticCapsAndDefaultsCallbacks(sandboxed),
      remote_id,
      mojom::PrinterSemanticCapsAndDefaultsResult::NewResultCode(
          mojom::ResultCode::kFailed));
  RunSavedCallbacksStructResult(
      GetRemoteSavedUseDefaultSettingsCallbacks(sandboxed), remote_id,
      mojom::PrintSettingsResult::NewResultCode(mojom::ResultCode::kFailed));
#if BUILDFLAG(IS_WIN)
  RunSavedCallbacksStructResult(
      GetRemoteSavedAskUserForSettingsCallbacks(sandboxed), remote_id,
      mojom::PrintSettingsResult::NewResultCode(mojom::ResultCode::kFailed));
#endif
  RunSavedCallbacksStructResult(
      GetRemoteSavedUpdatePrintSettingsCallbacks(sandboxed), remote_id,
      mojom::PrintSettingsResult::NewResultCode(mojom::ResultCode::kFailed));
  RunSavedCallbacks(GetRemoteSavedStartPrintingCallbacks(sandboxed), remote_id,
                    mojom::ResultCode::kFailed);
#if BUILDFLAG(IS_WIN)
  RunSavedCallbacks(GetRemoteSavedRenderPrintedPageCallbacks(sandboxed),
                    remote_id, mojom::ResultCode::kFailed);
#endif
  RunSavedCallbacks(GetRemoteSavedRenderPrintedDocumentCallbacks(sandboxed),
                    remote_id, mojom::ResultCode::kFailed);
  RunSavedCallbacks(GetRemoteSavedDocumentDoneCallbacks(sandboxed), remote_id,
                    mojom::ResultCode::kFailed);
  RunSavedCallbacks(GetRemoteSavedCancelCallbacks(sandboxed), remote_id);
}

PrintBackendServiceManager::RemoteSavedEnumeratePrintersCallbacks&
PrintBackendServiceManager::GetRemoteSavedEnumeratePrintersCallbacks(
    bool sandboxed) {
  return sandboxed ? sandboxed_saved_enumerate_printers_callbacks_
                   : unsandboxed_saved_enumerate_printers_callbacks_;
}

PrintBackendServiceManager::RemoteSavedFetchCapabilitiesCallbacks&
PrintBackendServiceManager::GetRemoteSavedFetchCapabilitiesCallbacks(
    bool sandboxed) {
  return sandboxed ? sandboxed_saved_fetch_capabilities_callbacks_
                   : unsandboxed_saved_fetch_capabilities_callbacks_;
}

PrintBackendServiceManager::RemoteSavedGetDefaultPrinterNameCallbacks&
PrintBackendServiceManager::GetRemoteSavedGetDefaultPrinterNameCallbacks(
    bool sandboxed) {
  return sandboxed ? sandboxed_saved_get_default_printer_name_callbacks_
                   : unsandboxed_saved_get_default_printer_name_callbacks_;
}

PrintBackendServiceManager::
    RemoteSavedGetPrinterSemanticCapsAndDefaultsCallbacks&
    PrintBackendServiceManager::
        GetRemoteSavedGetPrinterSemanticCapsAndDefaultsCallbacks(
            bool sandboxed) {
  return sandboxed
             ? sandboxed_saved_get_printer_semantic_caps_and_defaults_callbacks_
             : unsandboxed_saved_get_printer_semantic_caps_and_defaults_callbacks_;
}

PrintBackendServiceManager::RemoteSavedUseDefaultSettingsCallbacks&
PrintBackendServiceManager::GetRemoteSavedUseDefaultSettingsCallbacks(
    bool sandboxed) {
  return sandboxed ? sandboxed_saved_use_default_settings_callbacks_
                   : unsandboxed_saved_use_default_settings_callbacks_;
}

#if BUILDFLAG(IS_WIN)
PrintBackendServiceManager::RemoteSavedAskUserForSettingsCallbacks&
PrintBackendServiceManager::GetRemoteSavedAskUserForSettingsCallbacks(
    bool sandboxed) {
  return sandboxed ? sandboxed_saved_ask_user_for_settings_callbacks_
                   : unsandboxed_saved_ask_user_for_settings_callbacks_;
}
#endif

PrintBackendServiceManager::RemoteSavedUpdatePrintSettingsCallbacks&
PrintBackendServiceManager::GetRemoteSavedUpdatePrintSettingsCallbacks(
    bool sandboxed) {
  return sandboxed ? sandboxed_saved_update_print_settings_callbacks_
                   : unsandboxed_saved_update_print_settings_callbacks_;
}

PrintBackendServiceManager::RemoteSavedStartPrintingCallbacks&
PrintBackendServiceManager::GetRemoteSavedStartPrintingCallbacks(
    bool sandboxed) {
  return sandboxed ? sandboxed_saved_start_printing_callbacks_
                   : unsandboxed_saved_start_printing_callbacks_;
}

#if BUILDFLAG(IS_WIN)
PrintBackendServiceManager::RemoteSavedRenderPrintedPageCallbacks&
PrintBackendServiceManager::GetRemoteSavedRenderPrintedPageCallbacks(
    bool sandboxed) {
  return sandboxed ? sandboxed_saved_render_printed_page_callbacks_
                   : unsandboxed_saved_render_printed_page_callbacks_;
}
#endif

PrintBackendServiceManager::RemoteSavedRenderPrintedDocumentCallbacks&
PrintBackendServiceManager::GetRemoteSavedRenderPrintedDocumentCallbacks(
    bool sandboxed) {
  return sandboxed ? sandboxed_saved_render_printed_document_callbacks_
                   : unsandboxed_saved_render_printed_document_callbacks_;
}

PrintBackendServiceManager::RemoteSavedDocumentDoneCallbacks&
PrintBackendServiceManager::GetRemoteSavedDocumentDoneCallbacks(
    bool sandboxed) {
  return sandboxed ? sandboxed_saved_document_done_callbacks_
                   : unsandboxed_saved_document_done_callbacks_;
}

PrintBackendServiceManager::RemoteSavedCancelCallbacks&
PrintBackendServiceManager::GetRemoteSavedCancelCallbacks(bool sandboxed) {
  return sandboxed ? sandboxed_saved_cancel_callbacks_
                   : unsandboxed_saved_cancel_callbacks_;
}

const mojo::Remote<mojom::PrintBackendService>&
PrintBackendServiceManager::GetServiceAndCallbackContext(
    const std::string& printer_name,
    ClientType client_type,
    CallbackContext& context) {
  context.remote_id = GetRemoteIdForPrinterName(printer_name);
  context.saved_callback_id = base::UnguessableToken::Create();
  return GetService(printer_name, client_type, &context.is_sandboxed);
}

template <class... T, class... X>
void PrintBackendServiceManager::SaveCallback(
    RemoteSavedCallbacks<T...>& saved_callbacks,
    const RemoteId& remote_id,
    const base::UnguessableToken& saved_callback_id,
    base::OnceCallback<void(X...)> callback) {
  saved_callbacks[remote_id].emplace(saved_callback_id, std::move(callback));
}

template <class... T, class... X>
void PrintBackendServiceManager::ServiceCallbackDone(
    RemoteSavedCallbacks<T...>& saved_callbacks,
    const RemoteId& remote_id,
    const base::UnguessableToken& saved_callback_id,
    X... data) {
  auto found_callback_map = saved_callbacks.find(remote_id);
  DCHECK(found_callback_map != saved_callbacks.end());

  SavedCallbacks<T...>& callback_map = found_callback_map->second;

  auto callback_entry = callback_map.find(saved_callback_id);
  DCHECK(callback_entry != callback_map.end());
  base::OnceCallback<void(X...)> callback = std::move(callback_entry->second);
  callback_map.erase(callback_entry);

  // Done disconnect wrapper management, propagate the callback.
  std::move(callback).Run(std::forward<X>(data)...);
}

void PrintBackendServiceManager::OnDidEnumeratePrinters(
    const CallbackContext& context,
    mojom::PrinterListResultPtr printer_list) {
  LogCallbackFromRemote("EnumeratePrinters", context);
  ServiceCallbackDone(
      GetRemoteSavedEnumeratePrintersCallbacks(context.is_sandboxed),
      context.remote_id, context.saved_callback_id, std::move(printer_list));
}

void PrintBackendServiceManager::OnDidFetchCapabilities(
    const CallbackContext& context,
    mojom::PrinterCapsAndInfoResultPtr printer_caps_and_info) {
  LogCallbackFromRemote("FetchCapabilities", context);
  ServiceCallbackDone(
      GetRemoteSavedFetchCapabilitiesCallbacks(context.is_sandboxed),
      context.remote_id, context.saved_callback_id,
      std::move(printer_caps_and_info));
}

void PrintBackendServiceManager::OnDidGetDefaultPrinterName(
    const CallbackContext& context,
    mojom::DefaultPrinterNameResultPtr printer_name) {
  LogCallbackFromRemote("GetDefaultPrinterName", context);
  ServiceCallbackDone(
      GetRemoteSavedGetDefaultPrinterNameCallbacks(context.is_sandboxed),
      context.remote_id, context.saved_callback_id, std::move(printer_name));
}

void PrintBackendServiceManager::OnDidGetPrinterSemanticCapsAndDefaults(
    const CallbackContext& context,
    mojom::PrinterSemanticCapsAndDefaultsResultPtr printer_caps) {
  LogCallbackFromRemote("GetPrinterSemanticCapsAndDefaults", context);
  ServiceCallbackDone(GetRemoteSavedGetPrinterSemanticCapsAndDefaultsCallbacks(
                          context.is_sandboxed),
                      context.remote_id, context.saved_callback_id,
                      std::move(printer_caps));
}

void PrintBackendServiceManager::OnDidUseDefaultSettings(
    const CallbackContext& context,
    mojom::PrintSettingsResultPtr settings) {
  LogCallbackFromRemote("UseDefaultSettings", context);
  ServiceCallbackDone(
      GetRemoteSavedUseDefaultSettingsCallbacks(context.is_sandboxed),
      context.remote_id, context.saved_callback_id, std::move(settings));
}

#if BUILDFLAG(IS_WIN)
void PrintBackendServiceManager::OnDidAskUserForSettings(
    const CallbackContext& context,
    mojom::PrintSettingsResultPtr settings) {
  LogCallbackFromRemote("AskUserForSettings", context);
  ServiceCallbackDone(
      GetRemoteSavedAskUserForSettingsCallbacks(context.is_sandboxed),
      context.remote_id, context.saved_callback_id, std::move(settings));
}
#endif  // BUILDFLAG(IS_WIN)

void PrintBackendServiceManager::OnDidUpdatePrintSettings(
    const CallbackContext& context,
    mojom::PrintSettingsResultPtr settings) {
  LogCallbackFromRemote("UpdatePrintSettings", context);
  ServiceCallbackDone(
      GetRemoteSavedUpdatePrintSettingsCallbacks(context.is_sandboxed),
      context.remote_id, context.saved_callback_id, std::move(settings));
}

void PrintBackendServiceManager::OnDidStartPrinting(
    const CallbackContext& context,
    mojom::ResultCode result) {
  LogCallbackFromRemote("StartPrinting", context);
  ServiceCallbackDone(
      GetRemoteSavedStartPrintingCallbacks(context.is_sandboxed),
      context.remote_id, context.saved_callback_id, result);
}

#if BUILDFLAG(IS_WIN)
void PrintBackendServiceManager::OnDidRenderPrintedPage(
    const CallbackContext& context,
    mojom::ResultCode result) {
  LogCallbackFromRemote("RenderPrintedPage", context);
  ServiceCallbackDone(
      GetRemoteSavedRenderPrintedPageCallbacks(context.is_sandboxed),
      context.remote_id, context.saved_callback_id, result);
}
#endif

void PrintBackendServiceManager::OnDidRenderPrintedDocument(
    const CallbackContext& context,
    mojom::ResultCode result) {
  LogCallbackFromRemote("RenderPrintedDocument", context);
  ServiceCallbackDone(
      GetRemoteSavedRenderPrintedDocumentCallbacks(context.is_sandboxed),
      context.remote_id, context.saved_callback_id, result);
}

void PrintBackendServiceManager::OnDidDocumentDone(
    const CallbackContext& context,
    mojom::ResultCode result) {
  LogCallbackFromRemote("DocumentDone", context);
  ServiceCallbackDone(GetRemoteSavedDocumentDoneCallbacks(context.is_sandboxed),
                      context.remote_id, context.saved_callback_id, result);
}

void PrintBackendServiceManager::OnDidCancel(const CallbackContext& context) {
  LogCallbackFromRemote("Cancel", context);
  ServiceCallbackDone(GetRemoteSavedCancelCallbacks(context.is_sandboxed),
                      context.remote_id, context.saved_callback_id);
}

template <class T>
void PrintBackendServiceManager::RunSavedCallbacksStructResult(
    RemoteSavedStructCallbacks<T>& saved_callbacks,
    const RemoteId& remote_id,
    mojo::StructPtr<T> result_to_clone) {
  auto found_callbacks_map = saved_callbacks.find(remote_id);
  if (found_callbacks_map == saved_callbacks.end())
    return;  // No callbacks to run.

  SavedCallbacks<mojo::StructPtr<T>>& callbacks_map =
      found_callbacks_map->second;
  for (auto& iter : callbacks_map) {
    const base::UnguessableToken& saved_callback_id = iter.first;
    DVLOG(1) << "Propagating print backend callback, saved callback ID "
             << saved_callback_id << " for remote `" << remote_id << "`";

    // Don't remove entries from the map while we are iterating through it,
    // just run the callbacks.
    base::OnceCallback<void(mojo::StructPtr<T>)>& callback = iter.second;
    std::move(callback).Run(result_to_clone.Clone());
  }

  // Now that we're done iterating we can safely delete all of the callbacks.
  callbacks_map.clear();
}

template <class... T>
void PrintBackendServiceManager::RunSavedCallbacks(
    RemoteSavedCallbacks<T...>& saved_callbacks,
    const RemoteId& remote_id,
    T... result) {
  auto found_callbacks_map = saved_callbacks.find(remote_id);
  if (found_callbacks_map == saved_callbacks.end())
    return;  // No callbacks to run.

  SavedCallbacks<T...>& callbacks_map = found_callbacks_map->second;
  for (auto& iter : callbacks_map) {
    const base::UnguessableToken& saved_callback_id = iter.first;
    DVLOG(1) << "Propagating print backend callback, saved callback ID "
             << saved_callback_id << " for remote `" << remote_id << "`";

    // Don't remove entries from the map while we are iterating through it,
    // just run the callbacks.
    base::OnceCallback<void(T...)>& callback = iter.second;
    std::move(callback).Run(result...);
  }

  // Now that we're done iterating we can safely delete all of the callbacks.
  callbacks_map.clear();
}

// static
void PrintBackendServiceManager::SetClientsForTesting(
    const ClientsSet& query_clients,
    const ClientsSet& query_with_ui_clients,
    const PrintClientsMap& print_document_clients) {
  g_print_backend_service_manager_singleton->query_clients_ = query_clients;
  g_print_backend_service_manager_singleton->query_with_ui_clients_ =
      query_with_ui_clients;
  g_print_backend_service_manager_singleton->print_document_clients_ =
      print_document_clients;
}

}  // namespace printing
