Commit c3382554 authored by Justin Carlson's avatar Justin Carlson Committed by Commit Bot

Add documentation/design doc for Cups Printers Management.

Bug: 742487
Change-Id: If9d1b44ee3c967122fb21591c06117ea6709e767
Reviewed-on: https://chromium-review.googlesource.com/574893
Commit-Queue: Justin Carlson <justincarlson@chromium.org>
Reviewed-by: default avatarSean Kau <skau@chromium.org>
Cr-Commit-Position: refs/heads/master@{#487571}
parent e5e54f01
# ChromeOS Printing
This directory contains browser-side code for printing infrastructure in
ChromeOS. This directory primarily contains code dealing with local printing
via the Common Unix Printing System (CUPS), *not* Cloud Print.
## Other Related Directories
(Paths are given from the git root):
* `chromeos/printing/` - ChromeOS CUPS printing code that doesn't have
dependencies that require it to live in chrome/browser.
* `chrome/browser/ui/webui/settings/chromeos/` - ChromeOS printing settings
dialog backend support
* `chrome/browser/resources/settings/printing_page/` - Front end printer
settings code.
* `chrome/browser/printing/` - Cloud print support, and common print dialog
support.
## Printing Docs
* [Cups Printer Management](cups_printer_management.md) - Overview of how CUPS
printers are managed in ChromeOS.
# CUPS Printer Management in ChromeOS
One of the goals of CUPS printing in ChromeOS is to provide as smooth an
experience as possible to users who wish to print to CUPS printers. This means
we want to avoid extra setup steps where they are not necessary, and provide
help to the user when setup steps are necessary. This document covers several
different ways we might discover printers, and how they integrate into the
printing flows.
Note that this doc is, at present, a design for the future instead of a
description of the status quo. For up-to-date information on the implementation
refer to http://crbug.com/742487.
## Categorizing printers
The fact that CUPS supports many printing modalities means that we have a
mishmash of ways we could print. Within ChromeOS, we divide CUPS printers into
4 categories:
* *Configured* printers - These are printers that are saved as a part of a users'
settings and are synced across devices. They show up in the list of printers
in printer settings.
* *Enterprise* printers - Printers that are provided by an enterprise
environment. These are synced one-way to ChromeOS devices. If you work for
a company/attend a school using ChromeOS, these are the printers that your
administrator set up for you ahead of time. (These are currently called
"Recommended" printers in some APIs).
* *Automatic* printers - Printers that this user has never printed to, but we
believe the user *could* print to without needing to go through any manual
setup steps. Examples include Zeroconf printers and USB printers that either
do not need a PPD or for which we have identified with high confidence an
available PPD that can be installed if the user wants to print to this
device. If a user uses one of these printers, we automatically migrate it to
be a Configured printer, as the user has shown that this is a printer of
interest to them.
* *Discovered* printers - Printers that have been detected, but that we believe
will need user intervention to set up properly. Examples would be an
advertised zeroconf printer that can't be identified, or an unknown USB
printer.
The flow of printers through theses states is illustrated here:
![Printer Flow Chart](printer_flow_chart.png)
In terms of usage, the categories combine in these ways:
*Automatic* and *Discovered* printers appear in the settings Discovery dialog as
available printers to be added.
*Configured* printers appear in the list of printers in the settings dialog. The
plan of record is that we do *not* support user-configurability for *Enterprise*
printers, which means these will either not appear in settings, or appear there
in an uneditable way.
*Configured*, *Enterprise*, and *Automatic* printers appear in the print preview
dialog as available targets for printing.
## Code structure
### CupsPrintersManager
Defined in `chome/browser/chromeos/printing/cups_printers_manager.[cc|h]`.
The `CupsPrintersManager` class is the top-level object responsible for
providing information about available printers of all 4 types to all consumers.
It is instantiated on demand, and is not intended to be a long-lived structure;
it should be destroyed when its immediate usefulness is complete.
It provides this information both via an Observer interface, for consumers that
require live updates to changes in availability, and also via a simpler "Give me
all the printers of this type" interface for simpler consumers that just need to
know the state of the world at a given point in time. `CupsPrinterManager` is
also where the logic to determine whether a given detected printer is
automatically configurable (and this belongs in the *Automatic* category) or not
(and thus belongs in the *Discovered* category).
There are 4 primary consumers of `CupsPrintersManager` information:
* The ChromeOS Print Backend implementation
(`printing/backend/print_backend_chromeos.cc`). This is the ChromeOS
implementation of the backend print API used by Chrome.
* The PrintPreview dialog proxy
(`chrome/browser/ui/webui/print_preview/printer_backend_proxy_chromeos.cc`).
This is mostly a thread workaround to access the stuff in the print backend.
* The ChromeOS printers settings
page. (`chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc`
and related code). This is the primary place the user manages available
printers.
* `CupsPrintJobManager`. Requires printer information for the display and
management of print job notifications.
Currently the needs of these sites are served by a combination of
`PrintersManager` and direct access to `Detector` classes. Going forward, we
should make `CupsPrintersManager` the combined interface used by all of these
sites.
### SyncedPrintersManager
`SyncedPrintersManager` (nee `PrintersManager`) is a KeyedService Defined in
`chome/browser/chromeos/printing/printers_sync_manager.[cc|h]`.
`SyncedPrintersManager` manages the persistent data about printers that is
synced across devices. It serves as a two-way bridge between the sync systems
and `CupsPrintersManager` for both Configured and Enterprise printers.
Essentially, when the user changes their Configured printers list,
`SyncedPrintersManager` is what makes sure that propagates upstream, and when
changes from upstream come in, `SyncedPrintersManager` is responsible for
notifying `CupsPrintersManager` of the changes.
`SyncedPrintersManager` carries the additional responsibility for caching which
print destinations have been created in CUPS in the current session. CrOS
differs from most CUPS installations in that configuration information lives in
the user profile, and is only made available to CUPS as needed. In other words,
when a user wants to print, at that point Chrome tells CUPS to create the
relevant print queue, if needed. Print queues don’t persist across logins, and
are recreated as needed.
Additionally, although recreating the same print queue with the same options is
theoretically a null operation, cupsd can get somewhat unhappy if you attempt to
create the same destination too many times quickly. Thus, we need to cache
which destinations have been created in the current session.
This responsibility is given to `SyncedPrintersManager` because it is the only
long-lived piece of the printer management system. (NOTE: Is there any sort of
session-persistent key-value store that can be used in the browser? If so, we
can and should shift this responsibility to `CupsPrintersManager` directly. It
appears the KeyedService is the preferred way to do this sort of thing.)
### PrinterDetectors
Defined in `chome/browser/chromeos/printing/printer_detector.h` `PrinterDetector`
provides an interface implemented by subsystems that can automatically detect
the existence of printers.
These detections are used in two ways. First, detected printers that are not
previously-known Configured printers become either Automatic or Discovered
printers, depending on whether or not we believe they can be configured
automatically.
Second, `CupsPrintersManager` uses the detectors to determine whether or not
certain Configured printers are currently available. This impacts whether or
not they appear as print targets in the print UI.
Details for the existing PrinterDetector implementations follow.
#### USBPrinterDetector
Defined in `chome/browser/chromeos/printing/usb_printer_detector.[cc|h]`, this
interacts with the USB subsystem to turn USB device detection events into
printers. Both cold- and hot-plugged printers are supported.
#### ZeroconfPrinterDetector
Defined in `chome/browser/chromeos/printing/zeroconf_printer_detector.[cc|h]`,
this interacts with the DNS-SD and mDNS systems to detect printers that
advertise themselves on the local network.
// This is the source file for printer_flow_chart.svg.
//
// If you make changes, update the .png with this command:
//
// dot -Tpng printer_flow_chart.dot > printer_flow_chart.png
strict digraph printer_flow {
// Source nodes
newrank=true;
{
rank=same;
NEW_USB_PRINTER [label="A new USB\nprinter appears"];
NEW_ZEROCONF_PRINTER [label="A new zeroconf\nprinter appears"];
NEW_USER_PRINTER [label="User adds\nprinter in settings"];
NEW_ENTERPRISE_PRINTER [label="A new enterprise\nprinter appears"];
}
// Ending nodes
{
rank=same;
node [shape=doublecircle; margin=0];
CONFIGURED_PRINTERS [label="In CONFIGURED\nprinters list"];
ENTERPRISE_PRINTERS [label="In ENTERPRISE\nprinters list"];
AUTOMATIC_PRINTERS [label="In AUTOMATIC\nprinters list"];
DISCOVERED_PRINTERS [label="In DISCOVERED\nprinters list"];
DELETED [label="Deleted"; margin=.1];
}
AVAILABLE_AS_DISCOVERED [label="Available in settings\ndiscovery dialog";
rank=2];
CAN_AUTOCONFIGURE [label="Can be configured\nautomatically?";
shape=diamond];
CAN_AUTOCONFIGURE_YES [label="Yes"];
CAN_AUTOCONFIGURE_NO [label="No"];
USER_PRINTS [label="User prints\nusing printer"];
USER_REMOVES_IN_SETTINGS [label="User removes\nin settings"];
NEW_USB_PRINTER -> CAN_AUTOCONFIGURE;
NEW_ZEROCONF_PRINTER -> CAN_AUTOCONFIGURE;
NEW_ENTERPRISE_PRINTER -> ENTERPRISE_PRINTERS;
CAN_AUTOCONFIGURE -> CAN_AUTOCONFIGURE_YES;
CAN_AUTOCONFIGURE -> CAN_AUTOCONFIGURE_NO;
CAN_AUTOCONFIGURE_YES -> AUTOMATIC_PRINTERS;
CAN_AUTOCONFIGURE_NO -> DISCOVERED_PRINTERS;
AUTOMATIC_PRINTERS -> USER_PRINTS;
AUTOMATIC_PRINTERS -> AVAILABLE_AS_DISCOVERED;
DISCOVERED_PRINTERS -> AVAILABLE_AS_DISCOVERED;
AVAILABLE_AS_DISCOVERED -> NEW_USER_PRINTER;
USER_PRINTS -> CONFIGURED_PRINTERS;
NEW_USER_PRINTER -> CONFIGURED_PRINTERS;
CONFIGURED_PRINTERS -> USER_REMOVES_IN_SETTINGS;
USER_REMOVES_IN_SETTINGS -> NEW_ZEROCONF_PRINTER;
USER_REMOVES_IN_SETTINGS -> NEW_USB_PRINTER;
USER_REMOVES_IN_SETTINGS -> DELETED;
}
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment