blob: 91288f9a3e2d8d9cf301681109820e4c4d52f0d8 [file] [log] [blame]
// Copyright 2017 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/ash/printing/print_servers_manager.h"
#include <map>
#include <optional>
#include <utility>
#include "ash/public/cpp/network_config_service.h"
#include "base/functional/bind.h"
#include "base/metrics/histogram_functions.h"
#include "base/observer_list.h"
#include "chrome/browser/ash/printing/cups_printer_status_creator.h"
#include "chrome/browser/ash/printing/enterprise/print_servers_policy_provider.h"
#include "chrome/browser/ash/printing/enterprise/print_servers_provider.h"
#include "chrome/browser/ash/printing/ppd_provider_factory.h"
#include "chrome/browser/ash/printing/ppd_resolution_tracker.h"
#include "chrome/browser/ash/printing/printer_configurer.h"
#include "chrome/browser/ash/printing/printer_event_tracker.h"
#include "chrome/browser/ash/printing/printer_event_tracker_factory.h"
#include "chrome/browser/ash/printing/printer_info.h"
#include "chrome/browser/ash/printing/printers_map.h"
#include "chrome/browser/ash/printing/server_printers_provider.h"
#include "chrome/browser/ash/printing/synced_printers_manager.h"
#include "chrome/browser/ash/printing/synced_printers_manager_factory.h"
#include "chrome/browser/ash/printing/usb_printer_notification_controller.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
#include "chromeos/printing/cups_printer_status.h"
#include "chromeos/printing/printing_constants.h"
#include "chromeos/printing/uri.h"
#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h"
#include "components/device_event_log/device_event_log.h"
#include "components/policy/policy_constants.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_member.h"
#include "components/prefs/pref_service.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "printing/printer_query_result.h"
namespace ash {
PrintServersConfig::PrintServersConfig() = default;
PrintServersConfig::~PrintServersConfig() = default;
PrintServersConfig::PrintServersConfig(const PrintServersConfig&) = default;
PrintServersConfig& PrintServersConfig::operator=(const PrintServersConfig&) =
default;
namespace {
class PrintServersManagerImpl : public PrintServersManager {
public:
PrintServersManagerImpl(
std::unique_ptr<PrintServersPolicyProvider> print_servers_provider,
std::unique_ptr<ServerPrintersProvider> server_printers_provider)
: print_servers_provider_(std::move(print_servers_provider)),
server_printers_provider_(std::move(server_printers_provider)) {
print_servers_provider_->SetListener(
base::BindRepeating(&PrintServersManagerImpl::OnPrintServersUpdated,
weak_ptr_factory_.GetWeakPtr()));
server_printers_provider_->RegisterPrintersFoundCallback(
base::BindRepeating(&PrintServersManagerImpl::OnPrintersUpdated,
weak_ptr_factory_.GetWeakPtr()));
}
~PrintServersManagerImpl() override = default;
// Public API function.
void AddObserver(PrintServersManager::Observer* observer) override {
observer_list_.AddObserver(observer);
}
// Public API function.
void RemoveObserver(PrintServersManager::Observer* observer) override {
observer_list_.RemoveObserver(observer);
}
// Callback for ServerPrintersProvider.
void OnPrintersUpdated(bool complete) {
const std::vector<PrinterDetector::DetectedPrinter> printers =
server_printers_provider_->GetPrinters();
if (complete) {
PRINTER_LOG(EVENT) << "The list of server printers has been completed. "
<< "Number of server printers: " << printers.size();
}
for (auto& observer : observer_list_) {
observer.OnServerPrintersChanged(printers);
}
}
void OnPrintServersUpdated(bool is_complete,
std::map<GURL, PrintServer> print_servers,
ServerPrintersFetchingMode fetching_mode) {
fetching_mode_ = fetching_mode;
if (!is_complete) {
return;
}
// Create an entry in the device log.
if (is_complete) {
PRINTER_LOG(EVENT) << "The list of print servers has been completed. "
<< "Number of print servers: " << print_servers.size();
if (!print_servers.empty()) {
base::UmaHistogramCounts1000("Printing.PrintServers.ServersToQuery",
print_servers.size());
}
}
print_servers_ = std::map<std::string, PrintServer>();
std::vector<PrintServer> print_servers_list;
for (const auto& server_pair : print_servers) {
const PrintServer& server = server_pair.second;
print_servers_.value().emplace(server.GetId(), server);
print_servers_list.push_back(server);
}
if (fetching_mode_ == ServerPrintersFetchingMode::kSingleServerOnly) {
ChoosePrintServer(selected_print_server_ids_);
} else {
selected_print_server_ids_.clear();
server_printers_provider_->OnServersChanged(true, print_servers);
}
config_ = PrintServersConfig();
config_.print_servers = print_servers_list;
config_.fetching_mode = fetching_mode;
for (auto& observer : observer_list_) {
observer.OnPrintServersChanged(config_);
}
}
// Public API function.
void ChoosePrintServer(
const std::vector<std::string>& selected_print_server_ids) override {
if (fetching_mode_ != ServerPrintersFetchingMode::kSingleServerOnly ||
!print_servers_.has_value()) {
return;
}
std::map<GURL, PrintServer> selected_print_servers;
std::vector<std::string> selected_ids;
for (auto selected_print_server_id : selected_print_server_ids) {
auto iter = print_servers_.value().find(selected_print_server_id);
if (iter != print_servers_.value().end()) {
const PrintServer& server = iter->second;
selected_ids.push_back(selected_print_server_id);
selected_print_servers.emplace(server.GetUrl(), server);
}
}
selected_print_server_ids_ = selected_ids;
server_printers_provider_->OnServersChanged(true, selected_print_servers);
}
// Public API function.
PrintServersConfig GetPrintServersConfig() const override { return config_; }
private:
std::unique_ptr<PrintServersPolicyProvider> print_servers_provider_;
// The IDs of the currently selected print servers.
std::vector<std::string> selected_print_server_ids_;
ServerPrintersFetchingMode fetching_mode_;
std::optional<std::map<std::string, PrintServer>> print_servers_;
PrintServersConfig config_;
std::unique_ptr<ServerPrintersProvider> server_printers_provider_;
base::ObserverList<PrintServersManager::Observer>::Unchecked observer_list_;
base::WeakPtrFactory<PrintServersManagerImpl> weak_ptr_factory_{this};
};
} // namespace
// static
std::unique_ptr<PrintServersManager> PrintServersManager::Create(
Profile* profile) {
return std::make_unique<PrintServersManagerImpl>(
PrintServersPolicyProvider::Create(profile),
ServerPrintersProvider::Create(profile));
}
// static
std::unique_ptr<PrintServersManager> PrintServersManager::CreateForTesting(
std::unique_ptr<ServerPrintersProvider> server_printers_provider,
std::unique_ptr<PrintServersPolicyProvider> print_servers_provider) {
return std::make_unique<PrintServersManagerImpl>(
std::move(print_servers_provider), std::move(server_printers_provider));
}
// static
void PrintServersManager::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {
PrintServersProvider::RegisterProfilePrefs(registry);
}
// static
void PrintServersManager::RegisterLocalStatePrefs(
PrefRegistrySimple* registry) {
PrintServersProvider::RegisterLocalStatePrefs(registry);
}
} // namespace ash