Commit df87d813 authored by Justin Carlson's avatar Justin Carlson Committed by Commit Bot

Refactor SyncedPrintersManager.

This change brings SyncedPrintersManager closer to PrinterDetector
style interfaces, and aligns function names/styles with the design doc
for CUPS printers management.  It also removes a bunch of unique_ptr
wrapping of printers that are passed around, since these are not at
all performance critical and the unique_ptr stuff hampers readability
(and leads to subtle bugs when unique_ptrs are both used in a bind and
passed as a parameter at the same time).

Also convert it to the factory-function pattern while I'm mucking with
stuff and clean up the header.


Bug: 742487
Change-Id: Ibc9dd0a2f94dad8cb7a1f4adb1897668800311bf
Reviewed-on: https://chromium-review.googlesource.com/575289Reviewed-by: default avatarSky Malice <skym@chromium.org>
Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Reviewed-by: default avatarSean Kau <skau@chromium.org>
Commit-Queue: Justin Carlson <justincarlson@chromium.org>
Cr-Commit-Position: refs/heads/master@{#488276}
parent 7489031e
......@@ -49,61 +49,45 @@ bool UpdatePrinterPref(PrintersSyncBridge* sync_bridge,
return false;
}
} // anonymous namespace
SyncedPrintersManager::SyncedPrintersManager(
Profile* profile,
class SyncedPrintersManagerImpl : public SyncedPrintersManager {
public:
SyncedPrintersManagerImpl(Profile* profile,
std::unique_ptr<PrintersSyncBridge> sync_bridge)
: profile_(profile), sync_bridge_(std::move(sync_bridge)) {
pref_change_registrar_.Init(profile->GetPrefs());
pref_change_registrar_.Add(
prefs::kRecommendedNativePrinters,
base::Bind(&SyncedPrintersManager::UpdateRecommendedPrinters,
base::Bind(&SyncedPrintersManagerImpl::UpdateRecommendedPrinters,
base::Unretained(this)));
UpdateRecommendedPrinters();
}
SyncedPrintersManager::~SyncedPrintersManager() {}
// static
void SyncedPrintersManager::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {
registry->RegisterListPref(prefs::kPrintingDevices,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
registry->RegisterListPref(prefs::kRecommendedNativePrinters);
}
std::vector<std::unique_ptr<Printer>> SyncedPrintersManager::GetPrinters()
const {
std::vector<std::unique_ptr<Printer>> printers;
}
~SyncedPrintersManagerImpl() override = default;
std::vector<Printer> GetConfiguredPrinters() const override {
std::vector<Printer> printers;
std::vector<sync_pb::PrinterSpecifics> values =
sync_bridge_->GetAllPrinters();
for (const auto& value : values) {
printers.push_back(SpecificsToPrinter(value));
printers.push_back(*SpecificsToPrinter(value));
}
return printers;
}
std::vector<std::unique_ptr<Printer>>
SyncedPrintersManager::GetRecommendedPrinters() const {
std::vector<std::unique_ptr<Printer>> printers;
}
for (const std::string& key : recommended_printer_ids_) {
auto printer = recommended_printers_.find(key);
if (printer != recommended_printers_.end()) {
printers.push_back(base::MakeUnique<Printer>(*printer->second));
std::vector<Printer> GetEnterprisePrinters() const override {
std::vector<Printer> printers;
for (const std::string& key : enterprise_printer_ids_) {
auto printer = enterprise_printers_.find(key);
if (printer != enterprise_printers_.end()) {
printers.push_back(*printer->second);
}
}
return printers;
}
}
std::unique_ptr<Printer> SyncedPrintersManager::GetPrinter(
const std::string& printer_id) const {
std::unique_ptr<Printer> GetPrinter(
const std::string& printer_id) const override {
// check for a policy printer first
const auto& policy_printers = recommended_printers_;
const auto& policy_printers = enterprise_printers_;
auto found = policy_printers.find(printer_id);
if (found != policy_printers.end()) {
// Copy a printer.
......@@ -113,29 +97,22 @@ std::unique_ptr<Printer> SyncedPrintersManager::GetPrinter(
base::Optional<sync_pb::PrinterSpecifics> printer =
sync_bridge_->GetPrinter(printer_id);
return printer.has_value() ? SpecificsToPrinter(*printer) : nullptr;
}
}
void SyncedPrintersManager::RegisterPrinter(std::unique_ptr<Printer> printer) {
if (printer->id().empty()) {
printer->set_id(base::GenerateGUID());
void UpdateConfiguredPrinter(const Printer& printer_arg) override {
// Need a local copy since we may set the id.
Printer printer = printer_arg;
if (printer.id().empty()) {
printer.set_id(base::GenerateGUID());
}
DCHECK_EQ(Printer::SRC_USER_PREFS, printer->source());
bool new_printer =
UpdatePrinterPref(sync_bridge_.get(), printer->id(), *printer);
DCHECK_EQ(Printer::SRC_USER_PREFS, printer.source());
UpdatePrinterPref(sync_bridge_.get(), printer.id(), printer);
if (new_printer) {
for (Observer& obs : observers_) {
obs.OnPrinterAdded(*printer);
}
} else {
for (Observer& obs : observers_) {
obs.OnPrinterUpdated(*printer);
}
NotifyConfiguredObservers();
}
}
bool SyncedPrintersManager::RemovePrinter(const std::string& printer_id) {
bool RemoveConfiguredPrinter(const std::string& printer_id) override {
DCHECK(!printer_id.empty());
base::Optional<sync_pb::PrinterSpecifics> printer =
......@@ -145,32 +122,42 @@ bool SyncedPrintersManager::RemovePrinter(const std::string& printer_id) {
std::unique_ptr<Printer> p = SpecificsToPrinter(*printer);
success = sync_bridge_->RemovePrinter(p->id());
if (success) {
for (Observer& obs : observers_) {
obs.OnPrinterRemoved(*p);
}
NotifyConfiguredObservers();
}
} else {
LOG(WARNING) << "Could not find printer" << printer_id;
}
return success;
}
}
void SyncedPrintersManager::AddObserver(Observer* observer) {
void AddObserver(Observer* observer) override {
observers_.AddObserver(observer);
}
}
void SyncedPrintersManager::RemoveObserver(Observer* observer) {
void RemoveObserver(Observer* observer) override {
observers_.RemoveObserver(observer);
}
}
PrintersSyncBridge* SyncedPrintersManager::GetSyncBridge() {
return sync_bridge_.get();
}
void PrinterInstalled(const Printer& printer) override {
DCHECK(!printer.last_updated().is_null());
installed_printer_timestamps_[printer.id()] = printer.last_updated();
}
bool IsConfigurationCurrent(const Printer& printer) const override {
auto found = installed_printer_timestamps_.find(printer.id());
if (found == installed_printer_timestamps_.end())
return false;
// This method is not thread safe and could interact poorly with readers of
// |recommended_printers_|.
void SyncedPrintersManager::UpdateRecommendedPrinters() {
return found->second == printer.last_updated();
}
PrintersSyncBridge* GetSyncBridge() override { return sync_bridge_.get(); }
private:
// This method is not thread safe and could interact poorly with readers of
// |enterprise_printers_|.
void UpdateRecommendedPrinters() {
const PrefService* prefs = profile_->GetPrefs();
const base::ListValue* values =
......@@ -211,8 +198,8 @@ void SyncedPrintersManager::UpdateRecommendedPrinters() {
new_ids.push_back(id);
// Move existing printers, create othewise.
auto old = recommended_printers_.find(id);
if (old != recommended_printers_.end()) {
auto old = enterprise_printers_.find(id);
if (old != enterprise_printers_.end()) {
new_printers[id] = std::move(old->second);
} else {
auto printer =
......@@ -224,22 +211,61 @@ void SyncedPrintersManager::UpdateRecommendedPrinters() {
}
// Objects not in the most recent update get deallocated after method exit.
recommended_printer_ids_.swap(new_ids);
recommended_printers_.swap(new_printers);
}
enterprise_printer_ids_.swap(new_ids);
enterprise_printers_.swap(new_printers);
NotifyEnterpriseObservers();
}
void SyncedPrintersManager::PrinterInstalled(const Printer& printer) {
DCHECK(!printer.last_updated().is_null());
installed_printer_timestamps_[printer.id()] = printer.last_updated();
}
// Notify observers of a change in the set of Configured printers.
void NotifyConfiguredObservers() {
std::vector<Printer> printers = GetConfiguredPrinters();
for (Observer& obs : observers_) {
obs.OnConfiguredPrintersChanged(printers);
}
}
bool SyncedPrintersManager::IsConfigurationCurrent(
const Printer& printer) const {
auto found = installed_printer_timestamps_.find(printer.id());
if (found == installed_printer_timestamps_.end())
return false;
// Notify observers of a change in the set of Enterprise printers.
void NotifyEnterpriseObservers() {
std::vector<Printer> printers = GetEnterprisePrinters();
for (Observer& obs : observers_) {
obs.OnEnterprisePrintersChanged(printers);
}
}
return found->second == printer.last_updated();
private:
Profile* profile_;
PrefChangeRegistrar pref_change_registrar_;
// The backend for profile printers.
std::unique_ptr<PrintersSyncBridge> sync_bridge_;
// Contains the keys for all enterprise printers in order so we can return
// the list of enterprise printers in the order they were received.
std::vector<std::string> enterprise_printer_ids_;
std::map<std::string, std::unique_ptr<Printer>> enterprise_printers_;
// Map of printer ids to installation timestamps.
std::map<std::string, base::Time> installed_printer_timestamps_;
base::ObserverList<Observer> observers_;
};
} // namespace
// static
void SyncedPrintersManager::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {
registry->RegisterListPref(prefs::kPrintingDevices,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
registry->RegisterListPref(prefs::kRecommendedNativePrinters);
}
// static
std::unique_ptr<SyncedPrintersManager> SyncedPrintersManager::Create(
Profile* profile,
std::unique_ptr<PrintersSyncBridge> sync_bridge) {
return base::MakeUnique<SyncedPrintersManagerImpl>(profile,
std::move(sync_bridge));
}
} // namespace chromeos
......@@ -34,78 +34,59 @@ class SyncedPrintersManager : public KeyedService {
public:
class Observer {
public:
virtual void OnPrinterAdded(const Printer& printer) = 0;
virtual void OnPrinterUpdated(const Printer& printer) = 0;
virtual void OnPrinterRemoved(const Printer& printer) = 0;
virtual void OnConfiguredPrintersChanged(
const std::vector<Printer>& printers) = 0;
virtual void OnEnterprisePrintersChanged(
const std::vector<Printer>& printers) = 0;
};
SyncedPrintersManager(Profile* profile,
static std::unique_ptr<SyncedPrintersManager> Create(
Profile* profile,
std::unique_ptr<PrintersSyncBridge> sync_bridge);
~SyncedPrintersManager() override;
~SyncedPrintersManager() override = default;
// Register the printing preferences with the |registry|.
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
// Returns the printers that are saved in preferences.
std::vector<std::unique_ptr<Printer>> GetPrinters() const;
virtual std::vector<Printer> GetConfiguredPrinters() const = 0;
// Returns printers from enterprise policy.
std::vector<std::unique_ptr<Printer>> GetRecommendedPrinters() const;
virtual std::vector<Printer> GetEnterprisePrinters() const = 0;
// Returns the printer with id |printer_id|, or nullptr if no such
// printer exists.
std::unique_ptr<Printer> GetPrinter(const std::string& printer_id) const;
// Returns the printer with id |printer_id|, or nullptr if no such printer
// exists. Searches both Configured and Enterprise printers.
virtual std::unique_ptr<Printer> GetPrinter(
const std::string& printer_id) const = 0;
// Adds or updates a printer in profile preferences. The |printer| is
// identified by its id field. Those with an empty id are treated as new
// printers.
void RegisterPrinter(std::unique_ptr<Printer> printer);
virtual void UpdateConfiguredPrinter(const Printer& printer) = 0;
// Remove printer from preferences with the id |printer_id|. Returns true if
// the printer was successfully removed.
bool RemovePrinter(const std::string& printer_id);
virtual bool RemoveConfiguredPrinter(const std::string& printer_id) = 0;
// Attach |observer| for notification of events. |observer| is expected to
// live on the same thread (UI) as this object. OnPrinter* methods are
// invoked inline so calling RegisterPrinter in response to OnPrinterAdded is
// forbidden.
void AddObserver(SyncedPrintersManager::Observer* observer);
virtual void AddObserver(SyncedPrintersManager::Observer* observer) = 0;
// Remove |observer| so that it no longer receives notifications. After the
// completion of this method, the |observer| can be safely destroyed.
void RemoveObserver(SyncedPrintersManager::Observer* observer);
virtual void RemoveObserver(SyncedPrintersManager::Observer* observer) = 0;
// Returns a ModelTypeSyncBridge for the sync client.
PrintersSyncBridge* GetSyncBridge();
virtual PrintersSyncBridge* GetSyncBridge() = 0;
// Registers that the printer was installed in CUPS. This is independent of
// whether a printer is saved in profile preferences.
void PrinterInstalled(const Printer& printer);
virtual void PrinterInstalled(const Printer& printer) = 0;
// Returns true if |printer| is currently installed in CUPS.
bool IsConfigurationCurrent(const Printer& printer) const;
private:
// Updates the in-memory recommended printer list.
void UpdateRecommendedPrinters();
Profile* profile_;
PrefChangeRegistrar pref_change_registrar_;
// The backend for profile printers.
std::unique_ptr<PrintersSyncBridge> sync_bridge_;
// Contains the keys for all recommended printers in order so we can return
// the list of recommended printers in the order they were received.
std::vector<std::string> recommended_printer_ids_;
std::map<std::string, std::unique_ptr<Printer>> recommended_printers_;
// Map of printer ids to installation timestamps.
std::map<std::string, base::Time> installed_printer_timestamps_;
base::ObserverList<Observer> observers_;
DISALLOW_COPY_AND_ASSIGN(SyncedPrintersManager);
virtual bool IsConfigurationCurrent(const Printer& printer) const = 0;
};
} // namespace chromeos
......
......@@ -64,7 +64,8 @@ SyncedPrintersManager* SyncedPrintersManagerFactory::BuildServiceInstanceFor(
store_factory, base::BindRepeating(base::IgnoreResult(
&base::debug::DumpWithoutCrashing)));
return new SyncedPrintersManager(profile, std::move(sync_bridge));
return SyncedPrintersManager::Create(profile, std::move(sync_bridge))
.release();
}
} // namespace chromeos
......@@ -4,6 +4,7 @@
#include "chrome/browser/chromeos/printing/synced_printers_manager.h"
#include <algorithm>
#include <memory>
#include <utility>
......@@ -12,6 +13,7 @@
#include "base/memory/ptr_util.h"
#include "base/optional.h"
#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "chrome/browser/chromeos/printing/printers_sync_bridge.h"
#include "chrome/browser/chromeos/printing/synced_printers_manager_factory.h"
......@@ -30,7 +32,7 @@ namespace {
const char kTestPrinterId[] = "UUID-UUID-UUID-PRINTER";
const char kTestUri[] = "ipps://printer.chromium.org/ipp/print";
const char kLexJson[] = R"json({
const char kLexJson[] = R"({
"display_name": "LexaPrint",
"description": "Laser on the test shelf",
"manufacturer": "LexaPrint, Inc.",
......@@ -40,60 +42,43 @@ const char kLexJson[] = R"json({
"effective_manufacturer": "LexaPrint",
"effective_model": "MS610de",
},
} )json";
} )";
// Helper class to record observed events.
class LoggingObserver : public SyncedPrintersManager::Observer {
public:
void OnPrinterAdded(const Printer& printer) override {
last_added_ = printer;
void OnConfiguredPrintersChanged(
const std::vector<Printer>& printers) override {
configured_printers_ = printers;
}
void OnPrinterUpdated(const Printer& printer) override {
last_updated_ = printer;
void OnEnterprisePrintersChanged(
const std::vector<Printer>& printer) override {
enterprise_printers_ = printer;
}
void OnPrinterRemoved(const Printer& printer) override {
last_removed_ = printer;
const std::vector<Printer>& configured_printers() const {
return configured_printers_;
}
const std::vector<Printer>& enterprise_printers() const {
return enterprise_printers_;
}
// Returns true if OnPrinterAdded was called.
bool AddCalled() const { return last_added_.has_value(); }
// Returns true if OnPrinterUpdated was called.
bool UpdateCalled() const { return last_updated_.has_value(); }
// Returns true if OnPrinterRemoved was called.
bool RemoveCalled() const { return last_removed_.has_value(); }
// Returns the last printer that was added. If AddCalled is false, there will
// be no printer.
base::Optional<Printer> LastAdded() const { return last_added_; }
// Returns the last printer that was updated. If UpdateCalled is false, there
// will be no printer.
base::Optional<Printer> LastUpdated() const { return last_updated_; }
// Returns the last printer that was removed. If RemoveCalled is false, there
// will be no printer.
base::Optional<Printer> LastRemoved() const { return last_removed_; }
private:
base::Optional<Printer> last_added_;
base::Optional<Printer> last_updated_;
base::Optional<Printer> last_removed_;
std::vector<Printer> configured_printers_;
std::vector<Printer> enterprise_printers_;
};
} // namespace
class SyncedPrintersManagerTest : public testing::Test {
protected:
SyncedPrintersManagerTest()
: manager_(
: manager_(SyncedPrintersManager::Create(
&profile_,
base::MakeUnique<PrintersSyncBridge>(
base::Bind(&syncer::ModelTypeStore::CreateInMemoryStoreForTest,
syncer::PRINTERS),
base::BindRepeating(
base::IgnoreResult(&base::debug::DumpWithoutCrashing)))) {
base::IgnoreResult(&base::debug::DumpWithoutCrashing))))) {
base::RunLoop().RunUntilIdle();
}
......@@ -103,66 +88,84 @@ class SyncedPrintersManagerTest : public testing::Test {
// Must outlive |manager_|.
TestingProfile profile_;
SyncedPrintersManager manager_;
std::unique_ptr<SyncedPrintersManager> manager_;
};
// Add a test failure if the ids of printers are not those in expected. Order
// is not considered.
void ExpectPrinterIdsAre(const std::vector<Printer>& printers,
std::vector<std::string> expected_ids) {
std::sort(expected_ids.begin(), expected_ids.end());
std::vector<std::string> printer_ids;
for (const Printer& printer : printers) {
printer_ids.push_back(printer.id());
}
std::sort(printer_ids.begin(), printer_ids.end());
if (printer_ids != expected_ids) {
ADD_FAILURE() << "Expected to find ids: {"
<< base::JoinString(expected_ids, ",") << "}; found ids: {"
<< base::JoinString(printer_ids, ",") << "}";
}
}
TEST_F(SyncedPrintersManagerTest, AddPrinter) {
LoggingObserver observer;
manager_.AddObserver(&observer);
manager_.RegisterPrinter(base::MakeUnique<Printer>(kTestPrinterId));
manager_->AddObserver(&observer);
manager_->UpdateConfiguredPrinter(Printer(kTestPrinterId));
auto printers = manager_.GetPrinters();
auto printers = manager_->GetConfiguredPrinters();
ASSERT_EQ(1U, printers.size());
EXPECT_EQ(kTestPrinterId, printers[0]->id());
EXPECT_EQ(Printer::Source::SRC_USER_PREFS, printers[0]->source());
EXPECT_EQ(kTestPrinterId, printers[0].id());
EXPECT_EQ(Printer::Source::SRC_USER_PREFS, printers[0].source());
EXPECT_TRUE(observer.AddCalled());
EXPECT_FALSE(observer.UpdateCalled());
ExpectPrinterIdsAre(observer.configured_printers(), {kTestPrinterId});
}
TEST_F(SyncedPrintersManagerTest, UpdatePrinterAssignsId) {
manager_.RegisterPrinter(base::MakeUnique<Printer>());
manager_->UpdateConfiguredPrinter(Printer());
auto printers = manager_.GetPrinters();
auto printers = manager_->GetConfiguredPrinters();
ASSERT_EQ(1U, printers.size());
EXPECT_FALSE(printers[0]->id().empty());
EXPECT_FALSE(printers[0].id().empty());
}
TEST_F(SyncedPrintersManagerTest, UpdatePrinter) {
manager_.RegisterPrinter(base::MakeUnique<Printer>(kTestPrinterId));
auto updated_printer = base::MakeUnique<Printer>(kTestPrinterId);
updated_printer->set_uri(kTestUri);
manager_->UpdateConfiguredPrinter(Printer(kTestPrinterId));
Printer updated_printer(kTestPrinterId);
updated_printer.set_uri(kTestUri);
// Register observer so it only receives the update event.
LoggingObserver observer;
manager_.AddObserver(&observer);
manager_->AddObserver(&observer);
manager_.RegisterPrinter(std::move(updated_printer));
manager_->UpdateConfiguredPrinter(updated_printer);
auto printers = manager_.GetPrinters();
auto printers = manager_->GetConfiguredPrinters();
ASSERT_EQ(1U, printers.size());
EXPECT_EQ(kTestUri, printers[0]->uri());
EXPECT_EQ(kTestUri, printers[0].uri());
EXPECT_TRUE(observer.UpdateCalled());
EXPECT_FALSE(observer.AddCalled());
ExpectPrinterIdsAre(observer.configured_printers(), {kTestPrinterId});
}
TEST_F(SyncedPrintersManagerTest, RemovePrinter) {
manager_.RegisterPrinter(base::MakeUnique<Printer>("OtherUUID"));
manager_.RegisterPrinter(base::MakeUnique<Printer>(kTestPrinterId));
manager_.RegisterPrinter(base::MakeUnique<Printer>());
manager_->UpdateConfiguredPrinter(Printer("OtherUUID"));
manager_->UpdateConfiguredPrinter(Printer(kTestPrinterId));
manager_->UpdateConfiguredPrinter(Printer());
manager_->RemoveConfiguredPrinter(kTestPrinterId);
manager_.RemovePrinter(kTestPrinterId);
auto printers = manager_->GetConfiguredPrinters();
auto printers = manager_.GetPrinters();
// One of the remaining ids should be "OtherUUID", the other should have
// been automatically generated by the manager.
ASSERT_EQ(2U, printers.size());
EXPECT_NE(kTestPrinterId, printers.at(0)->id());
EXPECT_NE(kTestPrinterId, printers.at(1)->id());
EXPECT_NE(kTestPrinterId, printers.at(0).id());
EXPECT_NE(kTestPrinterId, printers.at(1).id());
}
// Tests for policy printers
TEST_F(SyncedPrintersManagerTest, RecommendedPrinters) {
TEST_F(SyncedPrintersManagerTest, EnterprisePrinters) {
std::string first_printer =
R"json({
"display_name": "Color Laser",
......@@ -188,14 +191,14 @@ TEST_F(SyncedPrintersManagerTest, RecommendedPrinters) {
// TestingPrefSyncableService assumes ownership of |value|.
prefs->SetManagedPref(prefs::kRecommendedNativePrinters, std::move(value));
auto printers = manager_.GetRecommendedPrinters();
auto printers = manager_->GetEnterprisePrinters();
ASSERT_EQ(2U, printers.size());
EXPECT_EQ("Color Laser", printers[0]->display_name());
EXPECT_EQ("ipp://192.168.1.5", printers[1]->uri());
EXPECT_EQ(Printer::Source::SRC_POLICY, printers[1]->source());
EXPECT_EQ("Color Laser", printers[0].display_name());
EXPECT_EQ("ipp://192.168.1.5", printers[1].uri());
EXPECT_EQ(Printer::Source::SRC_POLICY, printers[1].source());
}
TEST_F(SyncedPrintersManagerTest, GetRecommendedPrinter) {
TEST_F(SyncedPrintersManagerTest, GetEnterprisePrinter) {
std::string printer = kLexJson;
auto value = base::MakeUnique<base::ListValue>();
value->AppendString(printer);
......@@ -205,10 +208,10 @@ TEST_F(SyncedPrintersManagerTest, GetRecommendedPrinter) {
// TestingPrefSyncableService assumes ownership of |value|.
prefs->SetManagedPref(prefs::kRecommendedNativePrinters, std::move(value));
auto printers = manager_.GetRecommendedPrinters();
auto printers = manager_->GetEnterprisePrinters();
const Printer& from_list = *(printers.front());
std::unique_ptr<Printer> retrieved = manager_.GetPrinter(from_list.id());
const Printer& from_list = printers.front();
std::unique_ptr<Printer> retrieved = manager_->GetPrinter(from_list.id());
EXPECT_EQ(from_list.id(), retrieved->id());
EXPECT_EQ("LexaPrint", from_list.display_name());
......@@ -217,21 +220,22 @@ TEST_F(SyncedPrintersManagerTest, GetRecommendedPrinter) {
TEST_F(SyncedPrintersManagerTest, PrinterNotInstalled) {
Printer printer(kTestPrinterId, base::Time::FromInternalValue(1000));
EXPECT_FALSE(manager_.IsConfigurationCurrent(printer));
EXPECT_FALSE(manager_->IsConfigurationCurrent(printer));
}
TEST_F(SyncedPrintersManagerTest, PrinterIsInstalled) {
Printer printer(kTestPrinterId, base::Time::FromInternalValue(1000));
manager_.PrinterInstalled(printer);
EXPECT_TRUE(manager_.IsConfigurationCurrent(printer));
manager_->PrinterInstalled(printer);
EXPECT_TRUE(manager_->IsConfigurationCurrent(printer));
}
TEST_F(SyncedPrintersManagerTest, UpdatedPrinterConfiguration) {
Printer printer(kTestPrinterId, base::Time::FromInternalValue(1000));
manager_.PrinterInstalled(printer);
manager_->PrinterInstalled(printer);
Printer updated_printer(kTestPrinterId, base::Time::FromInternalValue(2000));
EXPECT_FALSE(manager_.IsConfigurationCurrent(updated_printer));
EXPECT_FALSE(manager_->IsConfigurationCurrent(updated_printer));
}
} // namespace
} // namespace chromeos
......@@ -261,11 +261,8 @@ class UsbPrinterDetectorImpl : public UsbPrinterDetector,
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (result == PrinterSetupResult::kSuccess) {
if (data->is_new) {
// We aren't done with data->printer yet, so we have to copy it instead
// of moving it.
auto printer_copy = base::MakeUnique<Printer>(*data->printer);
SyncedPrintersManagerFactory::GetForBrowserContext(profile_)
->RegisterPrinter(std::move(printer_copy));
->UpdateConfiguredPrinter(*data->printer);
}
// TODO(justincarlson): If the device was hotplugged, pop a timed
// notification that says the printer is now available for printing.
......
......@@ -26,7 +26,7 @@ namespace printers_helper {
namespace {
using PrinterList = std::vector<std::unique_ptr<chromeos::Printer>>;
using PrinterList = std::vector<chromeos::Printer>;
// Returns true if Printer#id, Printer#description, and Printer#uri all match.
bool PrintersAreMostlyEqual(const chromeos::Printer& left,
......@@ -40,16 +40,16 @@ bool ListsContainTheSamePrinters(const PrinterList& list_a,
const PrinterList& list_b) {
std::unordered_multimap<std::string, const chromeos::Printer*> map_b;
for (const auto& b : list_b) {
map_b.insert({b->id(), b.get()});
map_b.insert({b.id(), &b});
}
for (const auto& a : list_a) {
auto range = map_b.equal_range(a->id());
auto range = map_b.equal_range(a.id());
auto it = std::find_if(
range.first, range.second,
[&a](const std::pair<std::string, const chromeos::Printer*>& entry)
-> bool { return PrintersAreMostlyEqual(*a, *(entry.second)); });
-> bool { return PrintersAreMostlyEqual(a, *(entry.second)); });
if (it == range.second) {
// Element in a does not match an element in b. Lists do not contain the
......@@ -88,30 +88,30 @@ chromeos::SyncedPrintersManager* GetPrinterStore(
void AddPrinter(chromeos::SyncedPrintersManager* manager,
const chromeos::Printer& printer) {
manager->RegisterPrinter(base::MakeUnique<chromeos::Printer>(printer));
manager->UpdateConfiguredPrinter(printer);
}
void RemovePrinter(chromeos::SyncedPrintersManager* manager, int index) {
chromeos::Printer testPrinter(CreateTestPrinter(index));
manager->RemovePrinter(testPrinter.id());
manager->RemoveConfiguredPrinter(testPrinter.id());
}
bool EditPrinterDescription(chromeos::SyncedPrintersManager* manager,
int index,
const std::string& description) {
PrinterList printers = manager->GetPrinters();
PrinterList printers = manager->GetConfiguredPrinters();
std::string printer_id = PrinterId(index);
auto found = std::find_if(
printers.begin(), printers.end(),
[&printer_id](const std::unique_ptr<chromeos::Printer>& printer) -> bool {
return printer->id() == printer_id;
auto found =
std::find_if(printers.begin(), printers.end(),
[&printer_id](const chromeos::Printer& printer) -> bool {
return printer.id() == printer_id;
});
if (found == printers.end())
return false;
(*found)->set_description(description);
manager->RegisterPrinter(std::move(*found));
found->set_description(description);
manager->UpdateConfiguredPrinter(*found);
return true;
}
......@@ -139,17 +139,17 @@ chromeos::SyncedPrintersManager* GetPrinterStore(int index) {
}
int GetVerifierPrinterCount() {
return GetVerifierPrinterStore()->GetPrinters().size();
return GetVerifierPrinterStore()->GetConfiguredPrinters().size();
}
int GetPrinterCount(int index) {
return GetPrinterStore(index)->GetPrinters().size();
return GetPrinterStore(index)->GetConfiguredPrinters().size();
}
bool AllProfilesContainSamePrinters() {
auto reference_printers = GetPrinterStore(0)->GetPrinters();
auto reference_printers = GetPrinterStore(0)->GetConfiguredPrinters();
for (int i = 1; i < test()->num_clients(); ++i) {
auto printers = GetPrinterStore(i)->GetPrinters();
auto printers = GetPrinterStore(i)->GetConfiguredPrinters();
if (!ListsContainTheSamePrinters(reference_printers, printers)) {
VLOG(1) << "Printers in client [" << i << "] don't match client 0";
return false;
......@@ -160,8 +160,9 @@ bool AllProfilesContainSamePrinters() {
}
bool ProfileContainsSamePrintersAsVerifier(int index) {
return ListsContainTheSamePrinters(GetVerifierPrinterStore()->GetPrinters(),
GetPrinterStore(index)->GetPrinters());
return ListsContainTheSamePrinters(
GetVerifierPrinterStore()->GetConfiguredPrinters(),
GetPrinterStore(index)->GetConfiguredPrinters());
}
PrintersMatchChecker::PrintersMatchChecker()
......
......@@ -99,7 +99,7 @@ IN_PROC_BROWSER_TEST_F(TwoClientPrintersSyncTest, RemoveAndEditPrinters) {
ASSERT_TRUE(PrintersMatchChecker().Wait());
EXPECT_EQ(2, GetPrinterCount(0));
EXPECT_EQ(updated_description,
GetPrinterStore(1)->GetPrinters()[0]->description());
GetPrinterStore(1)->GetConfiguredPrinters()[0].description());
}
IN_PROC_BROWSER_TEST_F(TwoClientPrintersSyncTest, ConflictResolution) {
......@@ -125,7 +125,8 @@ IN_PROC_BROWSER_TEST_F(TwoClientPrintersSyncTest, ConflictResolution) {
// Conflict resolution shoud run here.
ASSERT_TRUE(PrintersMatchChecker().Wait());
// The more recent update should win.
EXPECT_EQ(valid_message, GetPrinterStore(1)->GetPrinters()[0]->description());
EXPECT_EQ(valid_message,
GetPrinterStore(1)->GetConfiguredPrinters()[0].description());
}
IN_PROC_BROWSER_TEST_F(TwoClientPrintersSyncTest, SimpleMerge) {
......
......@@ -52,11 +52,10 @@ printing::PrinterBasicInfo ToBasicInfo(const chromeos::Printer& printer) {
return basic_info;
}
void AddPrintersToList(
const std::vector<std::unique_ptr<chromeos::Printer>>& printers,
void AddPrintersToList(const std::vector<chromeos::Printer>& printers,
PrinterList* list) {
for (const auto& printer : printers) {
list->push_back(ToBasicInfo(*printer));
list->push_back(ToBasicInfo(printer));
}
}
......@@ -103,8 +102,8 @@ class PrinterBackendProxyChromeos : public PrinterBackendProxy {
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableNativeCups)) {
AddPrintersToList(prefs_->GetPrinters(), &printer_list);
AddPrintersToList(prefs_->GetRecommendedPrinters(), &printer_list);
AddPrintersToList(prefs_->GetConfiguredPrinters(), &printer_list);
AddPrintersToList(prefs_->GetEnterprisePrinters(), &printer_list);
}
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
......
......@@ -185,15 +185,13 @@ void CupsPrintersHandler::HandleGetCupsPrintersList(
std::string callback_id;
CHECK(args->GetString(0, &callback_id));
std::vector<std::unique_ptr<Printer>> printers =
std::vector<Printer> printers =
SyncedPrintersManagerFactory::GetForBrowserContext(profile_)
->GetPrinters();
->GetConfiguredPrinters();
auto printers_list = base::MakeUnique<base::ListValue>();
for (const std::unique_ptr<Printer>& printer : printers) {
std::unique_ptr<base::DictionaryValue> printer_info =
GetPrinterInfo(*printer.get());
printers_list->Append(std::move(printer_info));
for (const Printer& printer : printers) {
printers_list->Append(GetPrinterInfo(printer));
}
auto response = base::MakeUnique<base::DictionaryValue>();
......@@ -207,10 +205,10 @@ void CupsPrintersHandler::HandleUpdateCupsPrinter(const base::ListValue* args) {
CHECK(args->GetString(0, &printer_id));
CHECK(args->GetString(1, &printer_name));
std::unique_ptr<Printer> printer = base::MakeUnique<Printer>(printer_id);
printer->set_display_name(printer_name);
SyncedPrintersManagerFactory::GetForBrowserContext(profile_)->RegisterPrinter(
std::move(printer));
Printer printer(printer_id);
printer.set_display_name(printer_name);
SyncedPrintersManagerFactory::GetForBrowserContext(profile_)
->UpdateConfiguredPrinter(printer);
}
void CupsPrintersHandler::HandleRemoveCupsPrinter(const base::ListValue* args) {
......@@ -225,7 +223,7 @@ void CupsPrintersHandler::HandleRemoveCupsPrinter(const base::ListValue* args) {
return;
Printer::PrinterProtocol protocol = printer->GetProtocol();
prefs->RemovePrinter(printer_id);
prefs->RemoveConfiguredPrinter(printer_id);
DebugDaemonClient* client = DBusThreadManager::Get()->GetDebugDaemonClient();
client->CupsRemovePrinter(printer_name,
......@@ -355,19 +353,19 @@ void CupsPrintersHandler::HandleAddCupsPrinter(const base::ListValue* args) {
std::string printer_ppd_path;
printer_dict->GetString("printerPPDPath", &printer_ppd_path);
std::unique_ptr<Printer> printer = base::MakeUnique<Printer>(printer_id);
printer->set_display_name(printer_name);
printer->set_description(printer_description);
printer->set_manufacturer(printer_manufacturer);
printer->set_model(printer_model);
printer->set_uri(printer_uri);
Printer printer(printer_id);
printer.set_display_name(printer_name);
printer.set_description(printer_description);
printer.set_manufacturer(printer_manufacturer);
printer.set_model(printer_model);
printer.set_uri(printer_uri);
bool autoconf = false;
printer_dict->GetBoolean("printerAutoconf", &autoconf);
// Verify that the printer is autoconf or a valid ppd path is present.
if (autoconf) {
printer->mutable_ppd_reference()->autoconf = true;
printer.mutable_ppd_reference()->autoconf = true;
} else if (!printer_ppd_path.empty()) {
RecordPpdSource(kUser);
GURL tmp = net::FilePathToFileURL(base::FilePath(printer_ppd_path));
......@@ -376,24 +374,24 @@ void CupsPrintersHandler::HandleAddCupsPrinter(const base::ListValue* args) {
OnAddPrinterError();
return;
}
printer->mutable_ppd_reference()->user_supplied_ppd_url = tmp.spec();
printer.mutable_ppd_reference()->user_supplied_ppd_url = tmp.spec();
} else if (!ppd_manufacturer.empty() && !ppd_model.empty()) {
RecordPpdSource(kScs);
// Using the manufacturer and model, get a ppd reference.
if (!ppd_provider_->GetPpdReference(ppd_manufacturer, ppd_model,
printer->mutable_ppd_reference())) {
printer.mutable_ppd_reference())) {
LOG(ERROR) << "Failed to get ppd reference";
OnAddPrinterError();
return;
}
if (printer->make_and_model().empty()) {
if (printer.make_and_model().empty()) {
// In lieu of more accurate information, populate the make and model
// fields with the PPD information.
printer->set_manufacturer(ppd_manufacturer);
printer->set_model(ppd_model);
printer.set_manufacturer(ppd_manufacturer);
printer.set_model(ppd_model);
// PPD Model names are actually make and model.
printer->set_make_and_model(ppd_model);
printer.set_make_and_model(ppd_model);
}
} else {
// TODO(crbug.com/738514): Support PPD guessing for non-autoconf printers.
......@@ -402,28 +400,23 @@ void CupsPrintersHandler::HandleAddCupsPrinter(const base::ListValue* args) {
<< "A configuration option must have been selected to add a printer";
}
// Copy the printer for the configurer. Ownership needs to be transfered to
// the receiver of the callback.
const Printer printer_copy = *printer;
printer_configurer_->SetUpPrinter(
printer_copy,
base::Bind(&CupsPrintersHandler::OnAddedPrinter,
weak_factory_.GetWeakPtr(), base::Passed(&printer)));
printer, base::Bind(&CupsPrintersHandler::OnAddedPrinter,
weak_factory_.GetWeakPtr(), printer));
}
void CupsPrintersHandler::OnAddedPrinter(std::unique_ptr<Printer> printer,
void CupsPrintersHandler::OnAddedPrinter(const Printer& printer,
PrinterSetupResult result_code) {
std::string printer_name = printer->display_name();
UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PrinterSetupResult", result_code,
PrinterSetupResult::kMaxValue);
switch (result_code) {
case PrinterSetupResult::kSuccess: {
UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PrinterAdded",
printer->GetProtocol(), Printer::kProtocolMax);
printer.GetProtocol(), Printer::kProtocolMax);
auto* manager =
SyncedPrintersManagerFactory::GetForBrowserContext(profile_);
manager->PrinterInstalled(*printer);
manager->RegisterPrinter(std::move(printer));
manager->PrinterInstalled(printer);
manager->UpdateConfiguredPrinter(printer);
break;
}
case PrinterSetupResult::kPpdNotFound:
......@@ -452,7 +445,7 @@ void CupsPrintersHandler::OnAddedPrinter(std::unique_ptr<Printer> printer,
CallJavascriptFunction(
"cr.webUIListenerCallback", base::Value("on-add-cups-printer"),
base::Value(result_code == PrinterSetupResult::kSuccess),
base::Value(printer_name));
base::Value(printer.display_name()));
}
void CupsPrintersHandler::OnAddPrinterError() {
......
......@@ -68,8 +68,7 @@ class CupsPrintersHandler : public ::settings::SettingsPageUIHandler,
bool ipp_everywhere);
void HandleAddCupsPrinter(const base::ListValue* args);
void OnAddedPrinter(std::unique_ptr<Printer> printer,
PrinterSetupResult result);
void OnAddedPrinter(const Printer& printer, PrinterSetupResult result);
void OnAddPrinterError();
// Get a list of all manufacturers for which we have at least one model of
......
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