| 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 |