Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: chrome/browser/chromeos/printing/combining_printer_detector.cc

Issue 2945303005: Refactor PrinterDiscoverer and PrinterDetector to use a common interface. (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/printing/combining_printer_detector.h"
6
7 #include <map>
8 #include <utility>
9 #include <vector>
10
11 #include "base/memory/ptr_util.h"
12 #include "base/observer_list.h"
13 #include "base/scoped_observer.h"
14 #include "chrome/browser/chromeos/printing/printer_detector.h"
15 #include "chromeos/printing/printer_configuration.h"
16
17 namespace chromeos {
18 namespace {
19
20 class CombiningPrinterDetectorImpl;
21
22 // We can't just implement PrinterDetector::Observer in
23 // CombiningPrinterDetectorImpl because we need to be able to determing *which*
24 // underlying detector is giving us new information. Thus we use delegate
25 // instantions to allow for a disambiguation about the source of a
26 // PrinterDetector callback from one of the detectors being combined.
27 class ObserverDelegate : public PrinterDetector::Observer {
28 public:
29 ObserverDelegate(CombiningPrinterDetectorImpl* parent,
30 PrinterDetector* detector)
31 : parent_(parent), observer_(this) {
32 observer_.Add(detector);
33 }
34 void OnPrintersFound(const std::vector<Printer>& printers) override;
35 void OnPrinterScanComplete() override;
36
37 private:
38 CombiningPrinterDetectorImpl* parent_;
39 ScopedObserver<PrinterDetector, PrinterDetector::Observer> observer_;
40 };
41
42 class CombiningPrinterDetectorImpl : public CombiningPrinterDetector {
43 public:
44 ~CombiningPrinterDetectorImpl() override = default;
45
46 void AddDetector(PrinterDetector* detector) override {
47 detectors_.push_back(detector);
48 delegates_.push_back(base::MakeUnique<ObserverDelegate>(this, detector));
49 printers_.insert({delegates_.back().get(), detector->GetPrinters()});
50 scan_done_[delegates_.back().get()] = false;
51 }
52
53 void AddOwnedDetector(std::unique_ptr<PrinterDetector> detector) override {
54 AddDetector(detector.get());
55 owned_detectors_.emplace_back(std::move(detector));
56 }
57
58 // PrinterDetector implementations.
59 void AddObserver(PrinterDetector::Observer* observer) override {
60 observer_list_.AddObserver(observer);
61 }
62
63 void RemoveObserver(PrinterDetector::Observer* observer) override {
64 observer_list_.RemoveObserver(observer);
65 }
66
67 // Note this is *not* the PrinterDetectorObserver interface directly,
68 // it's the entry point for ObserverDelegates to pass along those messages
69 // into this class.
70 void OnPrintersFound(const ObserverDelegate* source,
71 const std::vector<Printer>& printers) {
72 // If this object doesn't know about the delegate trying to update its
73 // printers, we missed delegate registration somehow, which shouldn't
74 // happen.
75 DCHECK(base::ContainsKey(printers_, source));
76 printers_[source] = printers;
77 std::vector<Printer> all_printers = GetPrinters();
78 for (PrinterDetector::Observer& observer : observer_list_) {
79 observer.OnPrintersFound(all_printers);
80 }
81 }
82
83 void OnPrinterScanComplete(const ObserverDelegate* source) {
84 DCHECK(base::ContainsKey(printers_, source));
85 bool& scan_done = scan_done_[source];
86 if (!scan_done) {
87 scan_done = true;
88 for (const auto& entry : scan_done_) {
89 if (!entry.second) {
90 // Not all done yet.
91 return;
92 }
93 }
94 // Final outstanding scan just finished, notify observers.
95 for (PrinterDetector::Observer& observer : observer_list_) {
96 observer.OnPrinterScanComplete();
97 }
98 }
99 }
100
101 // Aggregate the printers from all underlying sources and return them.
102 std::vector<Printer> GetPrinters() override {
103 std::vector<Printer> ret;
104 for (const auto& entry : printers_) {
105 ret.insert(ret.end(), entry.second.begin(), entry.second.end());
106 }
107 return ret;
108 }
109
110 void Start() override {
111 for (PrinterDetector* detector : detectors_) {
112 detector->Start();
113 }
114 }
115
116 private:
117 // Map from observer delegate to the most recent list of printers from that
118 // observer.
119 std::map<const ObserverDelegate*, std::vector<Printer>> printers_;
120
121 // Map from observer delegate to whether or not that observer has completed
122 // its scan.
123 std::map<const ObserverDelegate*, bool> scan_done_;
124
125 // Observers of this object.
126 base::ObserverList<PrinterDetector::Observer> observer_list_;
127
128 std::vector<std::unique_ptr<PrinterDetector>> owned_detectors_;
129
130 // Memory management -- this just exists to ensure that the held
131 // elements get cleaned up.
132 std::vector<std::unique_ptr<ObserverDelegate>> delegates_;
133
134 // All detectors used by the combining detector, owned or unowned.
135 std::vector<PrinterDetector*> detectors_;
136 };
137
138 void ObserverDelegate::OnPrintersFound(const std::vector<Printer>& printers) {
139 parent_->OnPrintersFound(this, printers);
140 }
141
142 void ObserverDelegate::OnPrinterScanComplete() {
143 parent_->OnPrinterScanComplete(this);
144 }
145
146 } // namespace
147
148 // static
149 std::unique_ptr<CombiningPrinterDetector> CombiningPrinterDetector::Create() {
150 return base::MakeUnique<CombiningPrinterDetectorImpl>();
151 }
152
153 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698