chromium/chrome/browser/ash/printing/cups_printers_manager.h

// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ASH_PRINTING_CUPS_PRINTERS_MANAGER_H_
#define CHROME_BROWSER_ASH_PRINTING_CUPS_PRINTERS_MANAGER_H_

#include <memory>
#include <string>
#include <vector>

#include "base/functional/callback_forward.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list_types.h"
#include "base/scoped_observation_traits.h"
#include "chrome/browser/ash/printing/print_servers_manager.h"
#include "chrome/browser/ash/printing/printer_configurer.h"
#include "chrome/browser/ash/printing/printer_installation_manager.h"
#include "chromeos/printing/printer_configuration.h"
#include "chromeos/printing/uri.h"
#include "components/keyed_service/core/keyed_service.h"

class PrefRegistrySimple;
class PrefService;
class Profile;

namespace chromeos {
class PpdProvider;
}

namespace user_prefs {
class PrefRegistrySyncable;
}  // namespace user_prefs

namespace ash {

class DlcserviceClient;
class EnterprisePrintersProvider;
class PrinterDetector;
class PrinterEventTracker;
class SyncedPrintersManager;
class UsbPrinterNotificationController;

// Returns true if |printer_uri| is an IPP uri.
bool IsIppUri(const chromeos::Uri& printer_uri);

// Top level manager of available CUPS printers in ChromeOS.  All functions
// in this class must be called from a sequenced context.
class CupsPrintersManager : public PrinterInstallationManager,
                            public KeyedService {
 public:
  class Observer {
   public:
    // The list of printers in this class has changed to the given printers.
    virtual void OnPrintersChanged(
        chromeos::PrinterClass printer_class,
        const std::vector<chromeos::Printer>& printers) {}
    // It is called exactly once for each observer. It means that the
    // subsystem for enterprise printers is initialized. When an observer is
    // being registered after the subsystem's initialization, this call is
    // scheduled immediately in AddObserver method.
    virtual void OnEnterprisePrintersInitialized() {}

    virtual ~Observer() = default;
  };

  class LocalPrintersObserver : public base::CheckedObserver {
   public:
    // This endpoint is only triggered for the following scenarios:
    //   1. A new local printer is either plugged in or detected on the network.
    //   2. A local printer receives an updated printer status.
    virtual void OnLocalPrintersUpdated() {}

   protected:
    ~LocalPrintersObserver() override = default;
  };

  using PrinterStatusCallback =
      base::OnceCallback<void(const chromeos::CupsPrinterStatus&)>;

  // Factory function.
  static std::unique_ptr<CupsPrintersManager> Create(Profile* profile);

  // Factory function that allows injected dependencies, for testing.  Ownership
  // is not taken of any of the raw-pointer arguments.
  static std::unique_ptr<CupsPrintersManager> CreateForTesting(
      SyncedPrintersManager* synced_printers_manager,
      std::unique_ptr<PrinterDetector> usb_printer_detector,
      std::unique_ptr<PrinterDetector> zeroconf_printer_detector,
      scoped_refptr<chromeos::PpdProvider> ppd_provider,
      DlcserviceClient* dlc_service_client,
      std::unique_ptr<UsbPrinterNotificationController>
          usb_notification_controller,
      std::unique_ptr<PrintServersManager> print_servers_manager,
      std::unique_ptr<EnterprisePrintersProvider> enterprise_printers_provider,
      PrinterEventTracker* event_tracker,
      PrefService* pref_service);

  // Register the profile printing preferences with the |registry|.
  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);

  // Register the printing preferences with the |registry|.
  static void RegisterLocalStatePrefs(PrefRegistrySimple* registry);

  ~CupsPrintersManager() override = default;

  // Get the known printers in the given class.
  virtual std::vector<chromeos::Printer> GetPrinters(
      chromeos::PrinterClass printer_class) const = 0;

  // Saves |printer|. If |printer| already exists in the saved class, it will
  // be overwritten. This is a NOP if |printer| is an enterprise or USB printer.
  virtual void SavePrinter(const chromeos::Printer& printer) = 0;

  // Remove the saved printer with the given id.  This is a NOP if
  // the printer_id is not that of a saved printer.
  virtual void RemoveSavedPrinter(const std::string& printer_id) = 0;

  // Add or remove observers.  Observers must be on the same
  // sequence as the CupsPrintersManager.  Callbacks for a given observer
  // will be on the same sequence as the CupsPrintersManager.
  virtual void AddObserver(Observer* observer) = 0;
  virtual void RemoveObserver(Observer* observer) = 0;
  virtual void AddLocalPrintersObserver(LocalPrintersObserver* observer) = 0;
  virtual void RemoveLocalPrintersObserver(LocalPrintersObserver* observer) = 0;

  // Implementation of PrinterInstallationManager interface.
  bool IsPrinterInstalled(const chromeos::Printer& printer) const override = 0;
  void SetUpPrinter(const chromeos::Printer& printer,
                    bool is_automatic_installation,
                    PrinterSetupCallback callback) override = 0;
  void UninstallPrinter(const std::string& printer_id) override = 0;

  // Look for a printer with the given id in any class.  Returns a copy of the
  // printer if found, std::nullopt if not found.
  virtual std::optional<chromeos::Printer> GetPrinter(
      const std::string& id) const = 0;

  // Log an event that the user started trying to set up the given printer,
  // but setup was not completed for some reason.
  virtual void RecordSetupAbandoned(const chromeos::Printer& printer) = 0;

  // Performs individual printer status requests for each printer provided.
  // Passes retrieved printer status to the callbacks.
  virtual void FetchPrinterStatus(const std::string& printer_id,
                                  PrinterStatusCallback cb) = 0;

  // Records the total number of detected network printers and the
  // number of detected network printers that have not been saved.
  virtual void RecordNearbyNetworkPrinterCounts() const = 0;

  virtual PrintServersManager* GetPrintServersManager() const = 0;

  // Performs an IPP query on `printer` for autoconf compatibility.
  virtual void QueryPrinterForAutoConf(
      const chromeos::Printer& printer,
      base::OnceCallback<void(bool)> callback) = 0;
};

}  // namespace ash

namespace base {

template <>
struct ScopedObservationTraits<
    ash::CupsPrintersManager,
    ash::CupsPrintersManager::LocalPrintersObserver> {
  static void AddObserver(
      ash::CupsPrintersManager* source,
      ash::CupsPrintersManager::LocalPrintersObserver* observer) {
    source->AddLocalPrintersObserver(observer);
  }
  static void RemoveObserver(
      ash::CupsPrintersManager* source,
      ash::CupsPrintersManager::LocalPrintersObserver* observer) {
    source->RemoveLocalPrintersObserver(observer);
  }
};

}  // namespace base

#endif  // CHROME_BROWSER_ASH_PRINTING_CUPS_PRINTERS_MANAGER_H_