OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdint.h> | 5 #include <stdint.h> |
6 | 6 |
| 7 #include <map> |
7 #include <memory> | 8 #include <memory> |
| 9 #include <set> |
8 #include <utility> | 10 #include <utility> |
9 #include <vector> | 11 #include <vector> |
10 | 12 |
11 #include "base/bind.h" | 13 #include "base/bind.h" |
12 #include "base/bind_helpers.h" | 14 #include "base/bind_helpers.h" |
13 #include "base/macros.h" | 15 #include "base/macros.h" |
14 #include "base/memory/ptr_util.h" | 16 #include "base/memory/ptr_util.h" |
15 #include "base/observer_list_threadsafe.h" | 17 #include "base/observer_list_threadsafe.h" |
16 #include "base/scoped_observer.h" | 18 #include "base/scoped_observer.h" |
17 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
18 #include "base/synchronization/lock.h" | 20 #include "base/synchronization/lock.h" |
19 #include "base/threading/sequenced_task_runner_handle.h" | 21 #include "base/threading/sequenced_task_runner_handle.h" |
20 #include "chrome/browser/browser_process.h" | 22 #include "chrome/browser/browser_process.h" |
21 #include "chrome/browser/chromeos/printer_detector/printer_detector.h" | 23 #include "chrome/browser/chromeos/printer_detector/usb_printer_detector.h" |
22 #include "chrome/browser/chromeos/printing/ppd_provider_factory.h" | 24 #include "chrome/browser/chromeos/printing/ppd_provider_factory.h" |
23 #include "chrome/browser/chromeos/printing/printer_configurer.h" | 25 #include "chrome/browser/chromeos/printing/printer_configurer.h" |
24 #include "chrome/browser/chromeos/printing/printers_manager_factory.h" | 26 #include "chrome/browser/chromeos/printing/printers_manager_factory.h" |
25 #include "chrome/browser/chromeos/printing/usb_printer_util.h" | 27 #include "chrome/browser/chromeos/printing/usb_printer_util.h" |
26 #include "chrome/browser/chromeos/profiles/profile_helper.h" | 28 #include "chrome/browser/chromeos/profiles/profile_helper.h" |
27 #include "chromeos/dbus/dbus_thread_manager.h" | 29 #include "chromeos/dbus/dbus_thread_manager.h" |
28 #include "chromeos/dbus/debug_daemon_client.h" | 30 #include "chromeos/dbus/debug_daemon_client.h" |
29 #include "chromeos/printing/ppd_provider.h" | 31 #include "chromeos/printing/ppd_provider.h" |
30 #include "content/public/browser/browser_thread.h" | 32 #include "content/public/browser/browser_thread.h" |
31 #include "device/base/device_client.h" | 33 #include "device/base/device_client.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 // TODO(justincarlson): Possibly go deeper and query the IEEE1284 fields | 66 // TODO(justincarlson): Possibly go deeper and query the IEEE1284 fields |
65 // for make and model if we determine those are more likely to contain | 67 // for make and model if we determine those are more likely to contain |
66 // what we want. | 68 // what we want. |
67 std::string GuessEffectiveMakeAndModel(const device::UsbDevice& device) { | 69 std::string GuessEffectiveMakeAndModel(const device::UsbDevice& device) { |
68 return base::UTF16ToUTF8(device.manufacturer_string()) + " " + | 70 return base::UTF16ToUTF8(device.manufacturer_string()) + " " + |
69 base::UTF16ToUTF8(device.product_string()); | 71 base::UTF16ToUTF8(device.product_string()); |
70 } | 72 } |
71 | 73 |
72 // The PrinterDetector that drives the flow for setting up a USB printer to use | 74 // The PrinterDetector that drives the flow for setting up a USB printer to use |
73 // CUPS backend. | 75 // CUPS backend. |
74 class CupsPrinterDetectorImpl : public PrinterDetector, | 76 class UsbPrinterDetectorImpl : public UsbPrinterDetector, |
75 public device::UsbService::Observer { | 77 public device::UsbService::Observer { |
76 public: | 78 public: |
77 explicit CupsPrinterDetectorImpl(Profile* profile) | 79 explicit UsbPrinterDetectorImpl(Profile* profile) |
78 : profile_(profile), | 80 : profile_(profile), |
79 usb_observer_(this), | 81 usb_observer_(this), |
80 observer_list_( | 82 observer_list_( |
81 new base::ObserverListThreadSafe<PrinterDetector::Observer>), | 83 new base::ObserverListThreadSafe<UsbPrinterDetector::Observer>), |
82 weak_ptr_factory_(this) { | 84 weak_ptr_factory_(this) { |
83 device::UsbService* usb_service = | 85 device::UsbService* usb_service = |
84 device::DeviceClient::Get()->GetUsbService(); | 86 device::DeviceClient::Get()->GetUsbService(); |
85 if (usb_service) { | 87 if (usb_service) { |
86 usb_observer_.Add(usb_service); | 88 usb_observer_.Add(usb_service); |
87 usb_service->GetDevices(base::Bind(&CupsPrinterDetectorImpl::OnGetDevices, | 89 usb_service->GetDevices(base::Bind(&UsbPrinterDetectorImpl::OnGetDevices, |
88 weak_ptr_factory_.GetWeakPtr())); | 90 weak_ptr_factory_.GetWeakPtr())); |
89 } | 91 } |
90 } | 92 } |
91 ~CupsPrinterDetectorImpl() override = default; | 93 ~UsbPrinterDetectorImpl() override = default; |
92 | 94 |
93 // PrinterDetector interface function. | 95 // PrinterDetector interface function. |
94 void AddObserver(PrinterDetector::Observer* observer) override { | 96 void AddObserver(UsbPrinterDetector::Observer* observer) override { |
95 observer_list_->AddObserver(observer); | 97 observer_list_->AddObserver(observer); |
96 } | 98 } |
97 | 99 |
98 // PrinterDetector interface function. | 100 // PrinterDetector interface function. |
99 void RemoveObserver(PrinterDetector::Observer* observer) override { | 101 void RemoveObserver(UsbPrinterDetector::Observer* observer) override { |
100 observer_list_->RemoveObserver(observer); | 102 observer_list_->RemoveObserver(observer); |
101 } | 103 } |
102 | 104 |
103 // PrinterDetector interface function. | 105 // PrinterDetector interface function. |
104 std::vector<Printer> GetPrinters() override { | 106 std::vector<Printer> GetPrinters() override { |
105 base::AutoLock auto_lock(pp_lock_); | 107 base::AutoLock auto_lock(pp_lock_); |
106 return GetPrintersLocked(); | 108 return GetPrintersLocked(); |
107 } | 109 } |
108 | 110 |
109 private: | 111 private: |
(...skipping 29 matching lines...) Expand all Loading... |
139 return; | 141 return; |
140 } | 142 } |
141 | 143 |
142 base::AutoLock auto_lock(pp_lock_); | 144 base::AutoLock auto_lock(pp_lock_); |
143 if (base::ContainsKey(present_printers_, device->guid())) { | 145 if (base::ContainsKey(present_printers_, device->guid())) { |
144 present_printers_.erase(device->guid()); | 146 present_printers_.erase(device->guid()); |
145 auto printers = GetPrintersLocked(); | 147 auto printers = GetPrintersLocked(); |
146 // We already have pp_lock_, so need to call the pre-locked version of | 148 // We already have pp_lock_, so need to call the pre-locked version of |
147 // GetPrinters to prevent deadlock. | 149 // GetPrinters to prevent deadlock. |
148 observer_list_->Notify( | 150 observer_list_->Notify( |
149 FROM_HERE, &PrinterDetector::Observer::OnAvailableUsbPrintersChanged, | 151 FROM_HERE, |
| 152 &UsbPrinterDetector::Observer::OnAvailableUsbPrintersChanged, |
150 GetPrintersLocked()); | 153 GetPrintersLocked()); |
151 } else { | 154 } else { |
152 // If the device has been removed but it's not in present_printers_, it | 155 // If the device has been removed but it's not in present_printers_, it |
153 // must still be in the setup flow. | 156 // must still be in the setup flow. |
154 deferred_printer_removals_.insert(device->guid()); | 157 deferred_printer_removals_.insert(device->guid()); |
155 } | 158 } |
156 } | 159 } |
157 | 160 |
158 // If this device is a printer and we haven't already tried to set it up, | 161 // If this device is a printer and we haven't already tried to set it up, |
159 // starts the process of setting the printer up. |hotplugged| | 162 // starts the process of setting the printer up. |hotplugged| |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 // | 199 // |
197 // TODO(justincarlson): Add a notification that we are attempting to set up | 200 // TODO(justincarlson): Add a notification that we are attempting to set up |
198 // this printer at this point. | 201 // this printer at this point. |
199 data->is_new = true; | 202 data->is_new = true; |
200 | 203 |
201 // Look for an exact match based on USB ids. | 204 // Look for an exact match based on USB ids. |
202 scoped_refptr<PpdProvider> ppd_provider = | 205 scoped_refptr<PpdProvider> ppd_provider = |
203 printing::CreateProvider(profile_); | 206 printing::CreateProvider(profile_); |
204 ppd_provider->ResolveUsbIds( | 207 ppd_provider->ResolveUsbIds( |
205 device->vendor_id(), device->product_id(), | 208 device->vendor_id(), device->product_id(), |
206 base::Bind(&CupsPrinterDetectorImpl::ResolveUsbIdsDone, | 209 base::Bind(&UsbPrinterDetectorImpl::ResolveUsbIdsDone, |
207 weak_ptr_factory_.GetWeakPtr(), ppd_provider, | 210 weak_ptr_factory_.GetWeakPtr(), ppd_provider, |
208 base::Passed(std::move(data)))); | 211 base::Passed(std::move(data)))); |
209 } | 212 } |
210 | 213 |
211 void OnPrinterResolved(std::unique_ptr<SetUpPrinterData> data) { | 214 void OnPrinterResolved(std::unique_ptr<SetUpPrinterData> data) { |
212 // |data| will be invalidated by the move below, so we have to latch it | 215 // |data| will be invalidated by the move below, so we have to latch it |
213 // before the call. | 216 // before the call. |
214 SetUpPrinterData* data_ptr = data.get(); | 217 SetUpPrinterData* data_ptr = data.get(); |
215 data_ptr->configurer->SetUpPrinter( | 218 data_ptr->configurer->SetUpPrinter( |
216 *(data_ptr->printer), | 219 *(data_ptr->printer), |
217 base::Bind(&CupsPrinterDetectorImpl::SetUpPrinterDone, | 220 base::Bind(&UsbPrinterDetectorImpl::SetUpPrinterDone, |
218 weak_ptr_factory_.GetWeakPtr(), | 221 weak_ptr_factory_.GetWeakPtr(), |
219 base::Passed(std::move(data)))); | 222 base::Passed(std::move(data)))); |
220 } | 223 } |
221 | 224 |
222 // Called when the query for a driver based on usb ids completes. | 225 // Called when the query for a driver based on usb ids completes. |
223 // | 226 // |
224 // Note |provider| is not used in this function, it's just passed along to | 227 // Note |provider| is not used in this function, it's just passed along to |
225 // keep it alive during the USB resolution. | 228 // keep it alive during the USB resolution. |
226 void ResolveUsbIdsDone(scoped_refptr<PpdProvider> provider, | 229 void ResolveUsbIdsDone(scoped_refptr<PpdProvider> provider, |
227 std::unique_ptr<SetUpPrinterData> data, | 230 std::unique_ptr<SetUpPrinterData> data, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 // configuration settings. | 269 // configuration settings. |
267 | 270 |
268 if (base::ContainsKey(deferred_printer_removals_, data->device->guid())) { | 271 if (base::ContainsKey(deferred_printer_removals_, data->device->guid())) { |
269 // The device was removed before we finished the flow, so just don't add | 272 // The device was removed before we finished the flow, so just don't add |
270 // it to present_printers_; | 273 // it to present_printers_; |
271 deferred_printer_removals_.erase(data->device->guid()); | 274 deferred_printer_removals_.erase(data->device->guid()); |
272 } else { | 275 } else { |
273 base::AutoLock auto_lock(pp_lock_); | 276 base::AutoLock auto_lock(pp_lock_); |
274 present_printers_.emplace(data->device->guid(), std::move(data->printer)); | 277 present_printers_.emplace(data->device->guid(), std::move(data->printer)); |
275 observer_list_->Notify( | 278 observer_list_->Notify( |
276 FROM_HERE, &PrinterDetector::Observer::OnAvailableUsbPrintersChanged, | 279 FROM_HERE, |
| 280 &UsbPrinterDetector::Observer::OnAvailableUsbPrintersChanged, |
277 GetPrintersLocked()); | 281 GetPrintersLocked()); |
278 } | 282 } |
279 } | 283 } |
280 | 284 |
281 void SetNotificationUIManagerForTesting( | |
282 NotificationUIManager* manager) override { | |
283 LOG(FATAL) << "Not implemented for CUPS"; | |
284 } | |
285 | |
286 // Map from USB GUID to Printer that we have detected as being currently | 285 // Map from USB GUID to Printer that we have detected as being currently |
287 // plugged in and have finished processing. Note present_printers_ may be | 286 // plugged in and have finished processing. Note present_printers_ may be |
288 // accessed from multiple threads, so is protected by pp_lock_. | 287 // accessed from multiple threads, so is protected by pp_lock_. |
289 std::map<std::string, std::unique_ptr<Printer>> present_printers_; | 288 std::map<std::string, std::unique_ptr<Printer>> present_printers_; |
290 base::Lock pp_lock_; | 289 base::Lock pp_lock_; |
291 | 290 |
292 // If the usb device is removed before we've finished processing it, we'll | 291 // If the usb device is removed before we've finished processing it, we'll |
293 // defer the cleanup until the setup flow finishes. This is the set of | 292 // defer the cleanup until the setup flow finishes. This is the set of |
294 // guids which have been removed before the flow finished. | 293 // guids which have been removed before the flow finished. |
295 std::set<std::string> deferred_printer_removals_; | 294 std::set<std::string> deferred_printer_removals_; |
296 | 295 |
297 Profile* profile_; | 296 Profile* profile_; |
298 ScopedObserver<device::UsbService, device::UsbService::Observer> | 297 ScopedObserver<device::UsbService, device::UsbService::Observer> |
299 usb_observer_; | 298 usb_observer_; |
300 scoped_refptr<base::ObserverListThreadSafe<PrinterDetector::Observer>> | 299 scoped_refptr<base::ObserverListThreadSafe<UsbPrinterDetector::Observer>> |
301 observer_list_; | 300 observer_list_; |
302 base::WeakPtrFactory<CupsPrinterDetectorImpl> weak_ptr_factory_; | 301 base::WeakPtrFactory<UsbPrinterDetectorImpl> weak_ptr_factory_; |
303 }; | 302 }; |
304 | 303 |
305 } // namespace | 304 } // namespace |
306 | 305 |
307 // Nop base class implementation of GetPrinters(). Because this is non-empty we | |
308 // have to define it out-of-line. | |
309 std::vector<Printer> PrinterDetector::GetPrinters() { | |
310 return std::vector<Printer>(); | |
311 } | |
312 | |
313 // static | 306 // static |
314 std::unique_ptr<PrinterDetector> PrinterDetector::CreateCups(Profile* profile) { | 307 std::unique_ptr<UsbPrinterDetector> UsbPrinterDetector::Create( |
315 return base::MakeUnique<CupsPrinterDetectorImpl>(profile); | 308 Profile* profile) { |
| 309 return base::MakeUnique<UsbPrinterDetectorImpl>(profile); |
316 } | 310 } |
317 | 311 |
318 } // namespace chromeos | 312 } // namespace chromeos |
OLD | NEW |