| Index: chrome/browser/chromeos/printer_detector/cups_printer_detector.cc
|
| diff --git a/chrome/browser/chromeos/printer_detector/cups_printer_detector.cc b/chrome/browser/chromeos/printer_detector/cups_printer_detector.cc
|
| deleted file mode 100644
|
| index 00168bbf5c0a15f542cb5780575548fd78036fde..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/chromeos/printer_detector/cups_printer_detector.cc
|
| +++ /dev/null
|
| @@ -1,318 +0,0 @@
|
| -// Copyright 2017 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include <stdint.h>
|
| -
|
| -#include <memory>
|
| -#include <utility>
|
| -#include <vector>
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/bind_helpers.h"
|
| -#include "base/macros.h"
|
| -#include "base/memory/ptr_util.h"
|
| -#include "base/observer_list_threadsafe.h"
|
| -#include "base/scoped_observer.h"
|
| -#include "base/strings/utf_string_conversions.h"
|
| -#include "base/synchronization/lock.h"
|
| -#include "base/threading/sequenced_task_runner_handle.h"
|
| -#include "chrome/browser/browser_process.h"
|
| -#include "chrome/browser/chromeos/printer_detector/printer_detector.h"
|
| -#include "chrome/browser/chromeos/printing/ppd_provider_factory.h"
|
| -#include "chrome/browser/chromeos/printing/printer_configurer.h"
|
| -#include "chrome/browser/chromeos/printing/printers_manager_factory.h"
|
| -#include "chrome/browser/chromeos/printing/usb_printer_util.h"
|
| -#include "chrome/browser/chromeos/profiles/profile_helper.h"
|
| -#include "chromeos/dbus/dbus_thread_manager.h"
|
| -#include "chromeos/dbus/debug_daemon_client.h"
|
| -#include "chromeos/printing/ppd_provider.h"
|
| -#include "content/public/browser/browser_thread.h"
|
| -#include "device/base/device_client.h"
|
| -#include "device/usb/usb_device.h"
|
| -#include "device/usb/usb_device_filter.h"
|
| -#include "device/usb/usb_service.h"
|
| -
|
| -namespace chromeos {
|
| -namespace {
|
| -
|
| -using printing::PpdProvider;
|
| -
|
| -// Aggregates the information needed for printer setup so it's easier to pass it
|
| -// around.
|
| -struct SetUpPrinterData {
|
| - // The configurer running the SetUpPrinter call.
|
| - std::unique_ptr<PrinterConfigurer> configurer;
|
| -
|
| - // The printer being set up.
|
| - std::unique_ptr<Printer> printer;
|
| -
|
| - // The usb device causing this setup flow.
|
| - scoped_refptr<device::UsbDevice> device;
|
| -
|
| - // True if this printer is one that the user doesn't already have a
|
| - // configuration for.
|
| - bool is_new;
|
| -
|
| - // True if this was a printer that was plugged in during the session, false if
|
| - // it was already plugged in when the session started.
|
| - bool hotplugged;
|
| -};
|
| -
|
| -// Given a usb device, guesses the make and model for a driver lookup.
|
| -//
|
| -// TODO(justincarlson): Possibly go deeper and query the IEEE1284 fields
|
| -// for make and model if we determine those are more likely to contain
|
| -// what we want.
|
| -std::string GuessEffectiveMakeAndModel(const device::UsbDevice& device) {
|
| - return base::UTF16ToUTF8(device.manufacturer_string()) + " " +
|
| - base::UTF16ToUTF8(device.product_string());
|
| -}
|
| -
|
| -// The PrinterDetector that drives the flow for setting up a USB printer to use
|
| -// CUPS backend.
|
| -class CupsPrinterDetectorImpl : public PrinterDetector,
|
| - public device::UsbService::Observer {
|
| - public:
|
| - explicit CupsPrinterDetectorImpl(Profile* profile)
|
| - : profile_(profile),
|
| - usb_observer_(this),
|
| - observer_list_(
|
| - new base::ObserverListThreadSafe<PrinterDetector::Observer>),
|
| - weak_ptr_factory_(this) {
|
| - device::UsbService* usb_service =
|
| - device::DeviceClient::Get()->GetUsbService();
|
| - if (usb_service) {
|
| - usb_observer_.Add(usb_service);
|
| - usb_service->GetDevices(base::Bind(&CupsPrinterDetectorImpl::OnGetDevices,
|
| - weak_ptr_factory_.GetWeakPtr()));
|
| - }
|
| - }
|
| - ~CupsPrinterDetectorImpl() override = default;
|
| -
|
| - // PrinterDetector interface function.
|
| - void AddObserver(PrinterDetector::Observer* observer) override {
|
| - observer_list_->AddObserver(observer);
|
| - }
|
| -
|
| - // PrinterDetector interface function.
|
| - void RemoveObserver(PrinterDetector::Observer* observer) override {
|
| - observer_list_->RemoveObserver(observer);
|
| - }
|
| -
|
| - // PrinterDetector interface function.
|
| - std::vector<Printer> GetPrinters() override {
|
| - base::AutoLock auto_lock(pp_lock_);
|
| - return GetPrintersLocked();
|
| - }
|
| -
|
| - private:
|
| - std::vector<Printer> GetPrintersLocked() {
|
| - pp_lock_.AssertAcquired();
|
| - std::vector<Printer> printers;
|
| - printers.reserve(present_printers_.size());
|
| - for (const auto& entry : present_printers_) {
|
| - printers.push_back(*entry.second);
|
| - }
|
| - return printers;
|
| - }
|
| -
|
| - // Callback for initial enumeration of usb devices.
|
| - void OnGetDevices(
|
| - const std::vector<scoped_refptr<device::UsbDevice>>& devices) {
|
| - DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| - for (const auto& device : devices) {
|
| - MaybeSetUpDevice(device, false);
|
| - }
|
| - }
|
| -
|
| - // UsbService::observer override.
|
| - void OnDeviceAdded(scoped_refptr<device::UsbDevice> device) override {
|
| - DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| - MaybeSetUpDevice(device, true);
|
| - }
|
| -
|
| - // UsbService::observer override.
|
| - void OnDeviceRemoved(scoped_refptr<device::UsbDevice> device) override {
|
| - DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| - if (!UsbDeviceIsPrinter(*device)) {
|
| - return;
|
| - }
|
| -
|
| - base::AutoLock auto_lock(pp_lock_);
|
| - if (base::ContainsKey(present_printers_, device->guid())) {
|
| - present_printers_.erase(device->guid());
|
| - auto printers = GetPrintersLocked();
|
| - // We already have pp_lock_, so need to call the pre-locked version of
|
| - // GetPrinters to prevent deadlock.
|
| - observer_list_->Notify(
|
| - FROM_HERE, &PrinterDetector::Observer::OnAvailableUsbPrintersChanged,
|
| - GetPrintersLocked());
|
| - } else {
|
| - // If the device has been removed but it's not in present_printers_, it
|
| - // must still be in the setup flow.
|
| - deferred_printer_removals_.insert(device->guid());
|
| - }
|
| - }
|
| -
|
| - // If this device is a printer and we haven't already tried to set it up,
|
| - // starts the process of setting the printer up. |hotplugged|
|
| - // should be true if this was plugged in during the session.
|
| - void MaybeSetUpDevice(scoped_refptr<device::UsbDevice> device,
|
| - bool hotplugged) {
|
| - DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| -
|
| - if (!UsbDeviceIsPrinter(*device)) {
|
| - return;
|
| - }
|
| -
|
| - // If we got this far, we want to try to auto-configure this printer.
|
| - auto data = base::MakeUnique<SetUpPrinterData>();
|
| - data->configurer = PrinterConfigurer::Create(profile_);
|
| - data->device = device;
|
| - data->hotplugged = hotplugged;
|
| -
|
| - data->printer = UsbDeviceToPrinter(*device);
|
| - if (data->printer == nullptr) {
|
| - // We've failed to understand this printer device, an error will already
|
| - // have been logged, so just bail.
|
| - return;
|
| - }
|
| -
|
| - // If the user already has a configuration for this device, substitute that
|
| - // one for the one we generated automatically and skip the parts where we
|
| - // try to automagically figure out the driver.
|
| - std::unique_ptr<Printer> existing_printer_configuration =
|
| - PrintersManagerFactory::GetForBrowserContext(profile_)->GetPrinter(
|
| - data->printer->id());
|
| - if (existing_printer_configuration != nullptr) {
|
| - data->is_new = false;
|
| - data->printer = std::move(existing_printer_configuration);
|
| - OnPrinterResolved(std::move(data));
|
| - return;
|
| - }
|
| -
|
| - // It's not a device we have configured previously.
|
| - //
|
| - // TODO(justincarlson): Add a notification that we are attempting to set up
|
| - // this printer at this point.
|
| - data->is_new = true;
|
| -
|
| - // Look for an exact match based on USB ids.
|
| - scoped_refptr<PpdProvider> ppd_provider =
|
| - printing::CreateProvider(profile_);
|
| - ppd_provider->ResolveUsbIds(
|
| - device->vendor_id(), device->product_id(),
|
| - base::Bind(&CupsPrinterDetectorImpl::ResolveUsbIdsDone,
|
| - weak_ptr_factory_.GetWeakPtr(), ppd_provider,
|
| - base::Passed(std::move(data))));
|
| - }
|
| -
|
| - void OnPrinterResolved(std::unique_ptr<SetUpPrinterData> data) {
|
| - // |data| will be invalidated by the move below, so we have to latch it
|
| - // before the call.
|
| - SetUpPrinterData* data_ptr = data.get();
|
| - data_ptr->configurer->SetUpPrinter(
|
| - *(data_ptr->printer),
|
| - base::Bind(&CupsPrinterDetectorImpl::SetUpPrinterDone,
|
| - weak_ptr_factory_.GetWeakPtr(),
|
| - base::Passed(std::move(data))));
|
| - }
|
| -
|
| - // Called when the query for a driver based on usb ids completes.
|
| - //
|
| - // Note |provider| is not used in this function, it's just passed along to
|
| - // keep it alive during the USB resolution.
|
| - void ResolveUsbIdsDone(scoped_refptr<PpdProvider> provider,
|
| - std::unique_ptr<SetUpPrinterData> data,
|
| - PpdProvider::CallbackResultCode result,
|
| - const std::string& effective_make_and_model) {
|
| - DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| - if (result == PpdProvider::SUCCESS) {
|
| - // Got something based on usb ids. Go with it.
|
| - data->printer->mutable_ppd_reference()->effective_make_and_model =
|
| - effective_make_and_model;
|
| - } else {
|
| - // Couldn't figure this printer out based on usb ids, fall back to
|
| - // guessing the make/model string from what the USB system reports.
|
| - //
|
| - // TODO(justincarlson): Consider adding a mechanism for aggregating data
|
| - // about which usb devices are in the wild but unsupported?
|
| - data->printer->mutable_ppd_reference()->effective_make_and_model =
|
| - GuessEffectiveMakeAndModel(*data->device);
|
| - }
|
| - OnPrinterResolved(std::move(data));
|
| - }
|
| -
|
| - // Called with the result of asking to have a printer configured for CUPS. If
|
| - // |printer_to_register| is non-null and we successfully configured, then the
|
| - // printer is registered with the printers manager.
|
| - void SetUpPrinterDone(std::unique_ptr<SetUpPrinterData> data,
|
| - PrinterSetupResult result) {
|
| - 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);
|
| - PrintersManagerFactory::GetForBrowserContext(profile_)->RegisterPrinter(
|
| - std::move(printer_copy));
|
| - }
|
| - // TODO(justincarlson): If the device was hotplugged, pop a timed
|
| - // notification that says the printer is now available for printing.
|
| - }
|
| - // TODO(justincarlson): If this doesn't succeed, pop a notification that
|
| - // tells the user automatic setup failed and offers to open the CUPS printer
|
| - // configuration settings.
|
| -
|
| - if (base::ContainsKey(deferred_printer_removals_, data->device->guid())) {
|
| - // The device was removed before we finished the flow, so just don't add
|
| - // it to present_printers_;
|
| - deferred_printer_removals_.erase(data->device->guid());
|
| - } else {
|
| - base::AutoLock auto_lock(pp_lock_);
|
| - present_printers_.emplace(data->device->guid(), std::move(data->printer));
|
| - observer_list_->Notify(
|
| - FROM_HERE, &PrinterDetector::Observer::OnAvailableUsbPrintersChanged,
|
| - GetPrintersLocked());
|
| - }
|
| - }
|
| -
|
| - void SetNotificationUIManagerForTesting(
|
| - NotificationUIManager* manager) override {
|
| - LOG(FATAL) << "Not implemented for CUPS";
|
| - }
|
| -
|
| - // Map from USB GUID to Printer that we have detected as being currently
|
| - // plugged in and have finished processing. Note present_printers_ may be
|
| - // accessed from multiple threads, so is protected by pp_lock_.
|
| - std::map<std::string, std::unique_ptr<Printer>> present_printers_;
|
| - base::Lock pp_lock_;
|
| -
|
| - // If the usb device is removed before we've finished processing it, we'll
|
| - // defer the cleanup until the setup flow finishes. This is the set of
|
| - // guids which have been removed before the flow finished.
|
| - std::set<std::string> deferred_printer_removals_;
|
| -
|
| - Profile* profile_;
|
| - ScopedObserver<device::UsbService, device::UsbService::Observer>
|
| - usb_observer_;
|
| - scoped_refptr<base::ObserverListThreadSafe<PrinterDetector::Observer>>
|
| - observer_list_;
|
| - base::WeakPtrFactory<CupsPrinterDetectorImpl> weak_ptr_factory_;
|
| -};
|
| -
|
| -} // namespace
|
| -
|
| -// Nop base class implementation of GetPrinters(). Because this is non-empty we
|
| -// have to define it out-of-line.
|
| -std::vector<Printer> PrinterDetector::GetPrinters() {
|
| - return std::vector<Printer>();
|
| -}
|
| -
|
| -// static
|
| -std::unique_ptr<PrinterDetector> PrinterDetector::CreateCups(Profile* profile) {
|
| - return base::MakeUnique<CupsPrinterDetectorImpl>(profile);
|
| -}
|
| -
|
| -} // namespace chromeos
|
|
|