blob: 82a1b6088a5fdd63772fb78c9e1609fe26843e5d [file] [log] [blame]
// Copyright 2019 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/printers_map.h"
#include "base/containers/contains.h"
#include "base/containers/extend.h"
#include "base/containers/map_util.h"
namespace ash {
using ::chromeos::CupsPrinterStatus;
using ::chromeos::Printer;
using ::chromeos::PrinterClass;
namespace {
std::vector<Printer> GetPrintersAsVector(
const std::unordered_map<std::string, Printer>& printers_map,
bool only_secure) {
std::vector<Printer> printers;
for (const auto& [printer_id, printer] : printers_map) {
if (only_secure && !printer.HasSecureProtocol()) {
continue;
}
printers.push_back(printer);
}
return printers;
}
} // namespace
PrintersMap::PrintersMap() = default;
PrintersMap::~PrintersMap() = default;
std::optional<Printer> PrintersMap::Get(const std::string& printer_id) const {
for (const auto& [printer_class, printers_map] : printers_) {
if (auto* printer = base::FindOrNull(printers_map, printer_id)) {
return *printer;
}
}
return std::nullopt;
}
std::optional<Printer> PrintersMap::Get(PrinterClass printer_class,
const std::string& printer_id) const {
if (auto* printers_map = FindPrintersInClassOrNull(printer_class)) {
if (auto* printer = base::FindOrNull(*printers_map, printer_id)) {
return *printer;
}
}
return std::nullopt;
}
std::vector<Printer> PrintersMap::Get(PrinterClass printer_class) const {
if (auto* printers_map = FindPrintersInClassOrNull(printer_class)) {
return GetPrintersAsVector(*printers_map, /*only_secure=*/false);
}
return std::vector<Printer>();
}
std::vector<Printer> PrintersMap::Get() const {
std::vector<Printer> result;
for (const auto& [printer_class, printers_map] : printers_) {
base::Extend(result,
GetPrintersAsVector(printers_map, /*only_secure=*/false));
}
return result;
}
void PrintersMap::Insert(PrinterClass printer_class, const Printer& printer) {
DCHECK(!IsExistingPrinter(printer.id()));
printers_[printer_class][printer.id()] = printer;
}
void PrintersMap::Insert(PrinterClass printer_class,
const Printer& printer,
const CupsPrinterStatus& cups_printer_status) {
Insert(printer_class, printer);
printers_[printer_class][printer.id()].set_printer_status(
cups_printer_status);
}
void PrintersMap::Clear(PrinterClass printer_class) {
printers_[printer_class].clear();
}
void PrintersMap::ReplacePrintersInClass(PrinterClass printer_class,
const std::vector<Printer>& printers) {
// Get set of printer ids that initially existed in |printer_class| so the
// printers that aren't replaced by |printers| have their statuses deleted.
std::set<std::string> statuses_to_remove =
GetPrinterIdsInClass(printer_class);
Clear(printer_class);
for (const auto& printer : printers) {
// Printer was replaced so remove the id from the set so its status won't be
// deleted.
statuses_to_remove.erase(printer.id());
if (auto* printer_status =
base::FindOrNull(printer_statuses_, printer.id())) {
Insert(printer_class, printer, *printer_status);
continue;
}
Insert(printer_class, printer);
}
for (const std::string& printer_id : statuses_to_remove) {
printer_statuses_.erase(printer_id);
}
}
std::vector<Printer> PrintersMap::GetSecurePrinters() const {
std::vector<Printer> result;
for (const auto& [printer_class, printers_map] : printers_) {
base::Extend(result,
GetPrintersAsVector(printers_map, /*only_secure=*/true));
}
return result;
}
std::vector<Printer> PrintersMap::GetSecurePrinters(
PrinterClass printer_class) const {
if (auto* printers_map = FindPrintersInClassOrNull(printer_class)) {
return GetPrintersAsVector(*printers_map, /*only_secure=*/true);
}
return std::vector<Printer>();
}
void PrintersMap::Remove(PrinterClass printer_class,
const std::string& printer_id) {
if (!IsPrinterInClass(printer_class, printer_id)) {
return;
}
printers_[printer_class].erase(printer_id);
printer_statuses_.erase(printer_id);
DCHECK(!IsExistingPrinter(printer_id));
}
bool PrintersMap::IsPrinterInClass(PrinterClass printer_class,
const std::string& printer_id) const {
auto* printers_map = FindPrintersInClassOrNull(printer_class);
return printers_map ? base::Contains(*printers_map, printer_id) : false;
}
bool PrintersMap::IsExistingPrinter(const std::string& printer_id) const {
return Get(printer_id).has_value();
}
bool PrintersMap::SavePrinterStatus(
const std::string& printer_id,
const CupsPrinterStatus& cups_printer_status) {
printer_statuses_[printer_id] = cups_printer_status;
for (auto& [printer_class, printers_map] : printers_) {
if (auto* printer = base::FindOrNull(printers_map, printer_id)) {
const bool is_new_status =
printer->printer_status() != cups_printer_status;
printer->set_printer_status(cups_printer_status);
return is_new_status;
}
}
return false;
}
std::set<std::string> PrintersMap::GetPrinterIdsInClass(
PrinterClass printer_class) const {
std::set<std::string> result;
if (auto* printers_map = FindPrintersInClassOrNull(printer_class)) {
for (const auto& [printer_id, printer] : *printers_map) {
result.insert(printer.id());
}
}
return result;
}
const PrintersMap::PrintersInClassMap* PrintersMap::FindPrintersInClassOrNull(
chromeos::PrinterClass printer_class) const {
return base::FindOrNull(printers_, printer_class);
}
} // namespace ash