Commit bba4fd12 authored by Gavin Williams's avatar Gavin Williams Committed by Commit Bot

Add CupsPrinterStatus to the Printer object

- Add CupsPrinterStatus as a private member of the Printer object.

- Create a new map for caching and retrieving printer statuses.

- Add logic for serializing CupsPrinterStatus to JSON.

Bug: 1059607
Change-Id: I86c176df9d23f799486c521b604bebbac9611caa
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2118760Reviewed-by: default avatarZentaro Kavanagh <zentaro@chromium.org>
Reviewed-by: default avatarBailey Berro <baileyberro@chromium.org>
Commit-Queue: Gavin Williams <gavinwill@chromium.org>
Cr-Commit-Position: refs/heads/master@{#760178}
parent fa3f1204
...@@ -67,16 +67,43 @@ void PrintersMap::Insert(PrinterClass printer_class, const Printer& printer) { ...@@ -67,16 +67,43 @@ void PrintersMap::Insert(PrinterClass printer_class, const Printer& printer) {
printers_[printer_class][printer.id()] = printer; 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) { void PrintersMap::Clear(PrinterClass printer_class) {
printers_[printer_class].clear(); printers_[printer_class].clear();
} }
void PrintersMap::ReplacePrintersInClass(PrinterClass printer_class, void PrintersMap::ReplacePrintersInClass(PrinterClass printer_class,
const std::vector<Printer>& printers) { 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); Clear(printer_class);
for (const auto& printer : printers) { 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());
base::Optional<CupsPrinterStatus> printer_status =
GetPrinterStatus(printer.id());
if (printer_status) {
Insert(printer_class, printer, printer_status.value());
continue;
}
Insert(printer_class, printer); 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> PrintersMap::GetSecurePrinters() const {
...@@ -101,8 +128,9 @@ std::vector<Printer> PrintersMap::GetSecurePrinters( ...@@ -101,8 +128,9 @@ std::vector<Printer> PrintersMap::GetSecurePrinters(
result.reserve(printers_.at(printer_class).size()); result.reserve(printers_.at(printer_class).size());
for (const auto& kv : printers_.at(printer_class)) { for (const auto& kv : printers_.at(printer_class)) {
const Printer& printer = kv.second; const Printer& printer = kv.second;
if (printer.HasSecureProtocol()) if (printer.HasSecureProtocol()) {
result.push_back(printer); result.push_back(printer);
}
} }
return result; return result;
...@@ -114,6 +142,7 @@ void PrintersMap::Remove(PrinterClass printer_class, ...@@ -114,6 +142,7 @@ void PrintersMap::Remove(PrinterClass printer_class,
return; return;
} }
printers_[printer_class].erase(printer_id); printers_[printer_class].erase(printer_id);
printer_statuses_.erase(printer_id);
DCHECK(!IsExistingPrinter(printer_id)); DCHECK(!IsExistingPrinter(printer_id));
} }
...@@ -132,4 +161,40 @@ bool PrintersMap::IsExistingPrinter(const std::string& printer_id) const { ...@@ -132,4 +161,40 @@ bool PrintersMap::IsExistingPrinter(const std::string& printer_id) const {
return Get(printer_id).has_value(); return Get(printer_id).has_value();
} }
void PrintersMap::SavePrinterStatus(
const std::string& printer_id,
const CupsPrinterStatus& cups_printer_status) {
printer_statuses_[printer_id] = cups_printer_status;
for (auto& kv : printers_) {
std::unordered_map<std::string, Printer>& printers_map = kv.second;
auto printer_iter = printers_map.find(printer_id);
if (printer_iter != printers_map.end()) {
printer_iter->second.set_printer_status(cups_printer_status);
return;
}
}
}
base::Optional<CupsPrinterStatus> PrintersMap::GetPrinterStatus(
const std::string& printer_id) const {
auto printer_iter = printer_statuses_.find(printer_id);
if (printer_iter != printer_statuses_.end()) {
return printer_iter->second;
}
return base::nullopt;
}
std::set<std::string> PrintersMap::GetPrinterIdsInClass(
PrinterClass printer_class) const {
std::set<std::string> result;
if (HasPrintersInClass(printer_class)) {
for (const auto& kv : printers_.at(printer_class)) {
const Printer& printer = kv.second;
result.insert(printer.id());
}
}
return result;
}
} // namespace chromeos } // namespace chromeos
...@@ -5,12 +5,15 @@ ...@@ -5,12 +5,15 @@
#ifndef CHROME_BROWSER_CHROMEOS_PRINTING_PRINTERS_MAP_H_ #ifndef CHROME_BROWSER_CHROMEOS_PRINTING_PRINTERS_MAP_H_
#define CHROME_BROWSER_CHROMEOS_PRINTING_PRINTERS_MAP_H_ #define CHROME_BROWSER_CHROMEOS_PRINTING_PRINTERS_MAP_H_
#include <set>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include "base/containers/flat_map.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/optional.h" #include "base/optional.h"
#include "chromeos/printing/cups_printer_status.h"
#include "chromeos/printing/printer_configuration.h" #include "chromeos/printing/printer_configuration.h"
namespace chromeos { namespace chromeos {
...@@ -44,10 +47,16 @@ class PrintersMap { ...@@ -44,10 +47,16 @@ class PrintersMap {
// Adds |printer| to |printer_class|. // Adds |printer| to |printer_class|.
void Insert(PrinterClass printer_class, const Printer& printer); void Insert(PrinterClass printer_class, const Printer& printer);
// Adds |printer| with status |cups_printer_status| to |printer_class|.
void Insert(PrinterClass printer_class,
const Printer& printer,
const CupsPrinterStatus& cups_printer_status);
// Removes all printers in |printer_class|. // Removes all printers in |printer_class|.
void Clear(PrinterClass printer_class); void Clear(PrinterClass printer_class);
// Replaces the printers in |printer_class| with |printers|. // Replaces the printers in |printer_class| with |printers|. Adds a status to
// the printer if a status was previously saved in the printer status map.
void ReplacePrintersInClass(PrinterClass printer_class, void ReplacePrintersInClass(PrinterClass printer_class,
const std::vector<Printer>& printers); const std::vector<Printer>& printers);
...@@ -59,6 +68,11 @@ class PrintersMap { ...@@ -59,6 +68,11 @@ class PrintersMap {
bool IsPrinterInClass(PrinterClass printer_class, bool IsPrinterInClass(PrinterClass printer_class,
const std::string& printer_id) const; const std::string& printer_id) const;
// Adds printer status to existing printers in |printers_| map and also saves
// to |printer_statuses_| cache for future printer retrievals.
void SavePrinterStatus(const std::string& printer_id,
const CupsPrinterStatus& cups_printer_status);
private: private:
// Returns true if |printer_class| exists and contains at least 1 printer. // Returns true if |printer_class| exists and contains at least 1 printer.
bool HasPrintersInClass(PrinterClass printer_class) const; bool HasPrintersInClass(PrinterClass printer_class) const;
...@@ -66,11 +80,22 @@ class PrintersMap { ...@@ -66,11 +80,22 @@ class PrintersMap {
// Returns true if |printer_id| exists in any class. Used only for DCHECKs. // Returns true if |printer_id| exists in any class. Used only for DCHECKs.
bool IsExistingPrinter(const std::string& printer_id) const; bool IsExistingPrinter(const std::string& printer_id) const;
base::Optional<CupsPrinterStatus> GetPrinterStatus(
const std::string& printer_id) const;
// Returns set of printer id's for printers in class |printer_class|.
std::set<std::string> GetPrinterIdsInClass(PrinterClass printer_class) const;
// Categorized printers. Outer map keyed on PrinterClass, inner map keyed on // Categorized printers. Outer map keyed on PrinterClass, inner map keyed on
// PrinterId. // PrinterId.
std::unordered_map<PrinterClass, std::unordered_map<std::string, Printer>> std::unordered_map<PrinterClass, std::unordered_map<std::string, Printer>>
printers_; printers_;
// Stores printer statuses returned from performing printer status queries.
// This map is used to persist the printer statuses so when |printers_| map is
// rebuilt, all the statuses aren't lost. Key for this map is a printer id.
base::flat_map<std::string, CupsPrinterStatus> printer_statuses_;
DISALLOW_COPY_AND_ASSIGN(PrintersMap); DISALLOW_COPY_AND_ASSIGN(PrintersMap);
}; };
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/optional.h" #include "base/optional.h"
#include "chromeos/chromeos_export.h" #include "chromeos/chromeos_export.h"
#include "chromeos/printing/cups_printer_status.h"
#include "net/base/host_port_pair.h" #include "net/base/host_port_pair.h"
namespace net { namespace net {
...@@ -186,6 +187,11 @@ class CHROMEOS_EXPORT Printer { ...@@ -186,6 +187,11 @@ class CHROMEOS_EXPORT Printer {
// successfully parsed. // successfully parsed.
base::Optional<UriComponents> GetUriComponents() const; base::Optional<UriComponents> GetUriComponents() const;
const CupsPrinterStatus& printer_status() const { return printer_status_; }
void set_printer_status(const chromeos::CupsPrinterStatus& printer_status) {
printer_status_ = printer_status;
}
private: private:
// Globally unique identifier. Empty indicates a new printer. // Globally unique identifier. Empty indicates a new printer.
std::string id_; std::string id_;
...@@ -237,6 +243,9 @@ class CHROMEOS_EXPORT Printer { ...@@ -237,6 +243,9 @@ class CHROMEOS_EXPORT Printer {
// The datastore which holds this printer. // The datastore which holds this printer.
Source source_; Source source_;
// The current status of the printer
chromeos::CupsPrinterStatus printer_status_;
}; };
} // namespace chromeos } // namespace chromeos
......
...@@ -6,10 +6,12 @@ ...@@ -6,10 +6,12 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <utility>
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/values.h" #include "base/values.h"
#include "chromeos/printing/cups_printer_status.h"
#include "chromeos/printing/printer_configuration.h" #include "chromeos/printing/printer_configuration.h"
#include "chromeos/printing/uri_components.h" #include "chromeos/printing/uri_components.h"
...@@ -229,4 +231,27 @@ std::unique_ptr<base::DictionaryValue> GetCupsPrinterInfo( ...@@ -229,4 +231,27 @@ std::unique_ptr<base::DictionaryValue> GetCupsPrinterInfo(
return printer_info; return printer_info;
} }
base::Value CreateCupsPrinterStatusDictionary(
const CupsPrinterStatus& cups_printer_status) {
base::Value printer_status(base::Value::Type::DICTIONARY);
printer_status.SetKey("printerId",
base::Value(cups_printer_status.GetPrinterId()));
printer_status.SetKey(
"timestamp",
base::Value(cups_printer_status.GetTimestamp().ToJsTimeIgnoringNull()));
base::Value status_reasons(base::Value::Type::LIST);
for (auto reason : cups_printer_status.GetStatusReasons()) {
base::Value status_reason(base::Value::Type::DICTIONARY);
status_reason.SetKey("reason",
base::Value(static_cast<int>(reason.GetReason())));
status_reason.SetKey("severity",
base::Value(static_cast<int>(reason.GetSeverity())));
status_reasons.Append(std::move(status_reason));
}
printer_status.SetKey("status_reasons", std::move(status_reasons));
return printer_status;
}
} // namespace chromeos } // namespace chromeos
...@@ -12,10 +12,13 @@ ...@@ -12,10 +12,13 @@
namespace base { namespace base {
class DictionaryValue; class DictionaryValue;
class Value;
} }
namespace chromeos { namespace chromeos {
class CupsPrinterStatus;
CHROMEOS_EXPORT extern const char kPrinterId[]; CHROMEOS_EXPORT extern const char kPrinterId[];
// Returns a new printer populated with the fields from |pref|. Processes // Returns a new printer populated with the fields from |pref|. Processes
...@@ -29,6 +32,9 @@ CHROMEOS_EXPORT std::unique_ptr<Printer> RecommendedPrinterToPrinter( ...@@ -29,6 +32,9 @@ CHROMEOS_EXPORT std::unique_ptr<Printer> RecommendedPrinterToPrinter(
CHROMEOS_EXPORT std::unique_ptr<base::DictionaryValue> GetCupsPrinterInfo( CHROMEOS_EXPORT std::unique_ptr<base::DictionaryValue> GetCupsPrinterInfo(
const Printer& printer); const Printer& printer);
// Returns a JSON representation of a CupsPrinterStatus
CHROMEOS_EXPORT base::Value CreateCupsPrinterStatusDictionary(
const CupsPrinterStatus& cups_printer_status);
} // namespace chromeos } // namespace chromeos
#endif // CHROMEOS_PRINTING_PRINTER_TRANSLATOR_H_ #endif // CHROMEOS_PRINTING_PRINTER_TRANSLATOR_H_
...@@ -2,19 +2,23 @@ ...@@ -2,19 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include <utility> #include "chromeos/printing/printer_translator.h"
#include <string>
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/test/values_test_util.h" #include "base/test/values_test_util.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "base/values.h" #include "base/values.h"
#include "chromeos/printing/cups_printer_status.h"
#include "chromeos/printing/printer_configuration.h" #include "chromeos/printing/printer_configuration.h"
#include "chromeos/printing/printer_translator.h"
#include "testing/gmock/include/gmock/gmock-matchers.h" #include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace chromeos { namespace chromeos {
using CupsPrinterStatusReason = CupsPrinterStatus::CupsPrinterStatusReason;
namespace { namespace {
// Printer test data // Printer test data
...@@ -317,4 +321,61 @@ TEST(PrinterTranslatorTest, GetCupsPrinterInfoAutoconfPrinter) { ...@@ -317,4 +321,61 @@ TEST(PrinterTranslatorTest, GetCupsPrinterInfoAutoconfPrinter) {
ExpectDictBooleanValue(true, *printer_info, "printerPpdReference.autoconf"); ExpectDictBooleanValue(true, *printer_info, "printerPpdReference.autoconf");
} }
TEST(PrinterTranslatorTest, GetCupsPrinterStatusOneReason) {
CupsPrinterStatus cups_printer_status("id");
cups_printer_status.AddStatusReason(
CupsPrinterStatusReason::Reason::kDoorOpen,
CupsPrinterStatusReason::Severity::kError);
base::Value printer_status_dict =
CreateCupsPrinterStatusDictionary(cups_printer_status);
EXPECT_EQ("id", *printer_status_dict.FindStringPath("printerId"));
EXPECT_EQ(cups_printer_status.GetTimestamp().ToJsTimeIgnoringNull(),
*printer_status_dict.FindDoublePath("timestamp"));
const base::Value* status_reasons =
printer_status_dict.FindListPath("status_reasons");
EXPECT_EQ(1u, status_reasons->GetList().size());
for (const base::Value& status_reason : status_reasons->GetList()) {
EXPECT_EQ(static_cast<int>(CupsPrinterStatusReason::Reason::kDoorOpen),
*status_reason.FindIntPath("reason"));
EXPECT_EQ(static_cast<int>(CupsPrinterStatusReason::Severity::kError),
*status_reason.FindIntPath("severity"));
}
}
TEST(PrinterTranslatorTest, GetCupsPrinterStatusTwoReasons) {
CupsPrinterStatus cups_printer_status("id");
cups_printer_status.AddStatusReason(
CupsPrinterStatusReason::Reason::kLowOnPaper,
CupsPrinterStatusReason::Severity::kWarning);
cups_printer_status.AddStatusReason(
CupsPrinterStatusReason::Reason::kPaperJam,
CupsPrinterStatusReason::Severity::kError);
base::Value printer_status_dict =
CreateCupsPrinterStatusDictionary(cups_printer_status);
EXPECT_EQ("id", *printer_status_dict.FindStringPath("printerId"));
EXPECT_EQ(cups_printer_status.GetTimestamp().ToJsTimeIgnoringNull(),
*printer_status_dict.FindDoublePath("timestamp"));
const base::Value* status_reasons =
printer_status_dict.FindListPath("status_reasons");
auto status_reasons_list = status_reasons->GetList();
EXPECT_EQ(2u, status_reasons_list.size());
EXPECT_EQ(static_cast<int>(CupsPrinterStatusReason::Reason::kLowOnPaper),
status_reasons_list[0].FindIntPath("reason"));
EXPECT_EQ(static_cast<int>(CupsPrinterStatusReason::Severity::kWarning),
status_reasons_list[0].FindIntPath("severity"));
EXPECT_EQ(static_cast<int>(CupsPrinterStatusReason::Reason::kPaperJam),
status_reasons_list[1].FindIntPath("reason"));
EXPECT_EQ(static_cast<int>(CupsPrinterStatusReason::Severity::kError),
status_reasons_list[1].FindIntPath("severity"));
}
} // namespace chromeos } // namespace chromeos
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment