# vermilion10/printylan architecture

> Architecture diagram of the GitHub repository vermilion10/printylan, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-26). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/vermilion10/printylan
- Repository: https://github.com/vermilion10/printylan

## Overview

Printylan is an Android USB-printing app and print service. Its principal workflow discovers an attached printer, obtains USB access, reads the printer’s Device ID to select a language driver, then accepts a system print job, renders pages, encodes them for that printer, and sends the result over USB. The app also lets users select a PDF or image and override the detected driver per model. Major capabilities are documented in the README; wiring for unsampled UI and job-processing code is represented conservatively.

Main entry points: [`app/src/main/kotlin/com/printylan/service/PrintJobProcessor.kt`](https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/service/PrintJobProcessor.kt) (Job processor), [`app/src/main/kotlin/com/printylan/service/UsbDiscoverySession.kt`](https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/service/UsbDiscoverySession.kt) (Printer discovery), [`core/driver/src/main/kotlin/com/printylan/driver/DriverSelector.kt`](https://github.com/vermilion10/printylan/blob/main/core/driver/src/main/kotlin/com/printylan/driver/DriverSelector.kt) (Driver selection), [`app/src/main/kotlin/com/printylan/usb/PrinterProbe.kt`](https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/usb/PrinterProbe.kt) (Printer probe)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_app_ui["App interface"]
  node_main_activity["Main activity<br/>[MainActivity.kt]"]
  node_printers_screen["Printers screen<br/>[PrintersScreen.kt]"]
  node_main_viewmodel["Printer view model<br/>[MainViewModel.kt]"]
  node_file_printer["File printing<br/>[FilePrinter.kt]"]
  node_driver_preferences[("Driver overrides")]
end

subgraph group_printer_discovery["Printer discovery"]
  node_print_service["Print service"]
  node_discovery_session["Printer discovery"]
  node_usb_scanner["USB scanner"]
  node_usb_permissions["USB permissions<br/>[UsbPermissions.kt]"]
  node_printer_probe["Printer probe<br/>[PrinterProbe.kt]"]
  node_usb_connection["USB connection"]
  node_android_mapping["Print mapping"]
end

subgraph group_job_output["Print jobs"]
  node_job_processor["Job processor"]
  node_pdf_renderer["Banded PDF rendering<br/>[BandedPdfPage.kt]"]
end

subgraph group_driver_formats["Drivers and formats"]
  node_driver_selector["Driver selection<br/>[DriverSelector.kt]"]
  node_printer_driver["Driver interface<br/>[PrinterDriver.kt]"]
  node_pwg_driver["PWG Raster<br/>[PwgRasterDriver.kt]"]
  node_pcl_driver["PCL raster<br/>[PclRasterDriver.kt]"]
  node_pdf_driver["PDF passthrough"]
  node_canon_driver["Canon IVEC<br/>[CanonIvecDriver.kt]"]
  node_domain_models["Print domain types"]
end

node_user(("User"))
node_android_print(("Android print framework"))
node_usb_printer(("USB printer"))

node_user -->|"opens and selects"| node_main_activity
node_main_activity -->|"displays"| node_printers_screen
node_printers_screen -->|"requests printer actions"| node_main_viewmodel
node_main_activity -->|"starts file print"| node_file_printer
node_main_viewmodel -->|"saves override"| node_driver_preferences
node_main_viewmodel -->|"refreshes printers"| node_usb_scanner
node_android_print -->|"binds and queues jobs"| node_print_service
node_print_service -->|"creates session"| node_discovery_session
node_discovery_session -->|"refreshes and observes"| node_usb_scanner
node_discovery_session -->|"requests access"| node_usb_permissions
node_discovery_session -->|"inspects printer"| node_printer_probe
node_discovery_session -->|"maps capabilities"| node_android_mapping
node_usb_scanner -->|"detects attached device"| node_usb_printer
node_usb_permissions -->|"requests device access"| node_usb_printer
node_printer_probe -->|"opens for probing"| node_usb_connection
node_usb_connection -->|"reads ID and status"| node_usb_printer
node_printer_probe -->|"selects language"| node_driver_selector
node_printer_probe -->|"checks override"| node_driver_preferences
node_android_mapping -->|"maps capabilities"| node_domain_models
node_print_service -->|"queues or cancels"| node_job_processor
node_job_processor -->|"obtains printer access"| node_usb_permissions
node_job_processor -->|"gets printer driver"| node_printer_probe
node_job_processor -->|"renders PDF bands"| node_pdf_renderer
node_job_processor -->|"encodes rendered pages"| node_printer_driver
node_driver_selector -->|"selects by ID"| node_pwg_driver
node_driver_selector -->|"selects by ID"| node_pcl_driver
node_driver_selector -->|"selects by ID"| node_pdf_driver
node_driver_selector -->|"selects by ID"| node_canon_driver
node_pwg_driver -->|"implements"| node_printer_driver
node_pcl_driver -->|"implements"| node_printer_driver
node_pdf_driver -->|"implements"| node_printer_driver
node_canon_driver -->|"implements"| node_printer_driver
node_job_processor -->|"writes print stream"| node_usb_connection
node_usb_connection -->|"sends print data"| node_usb_printer

click node_main_activity "https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/ui/MainActivity.kt"
click node_printers_screen "https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/ui/PrintersScreen.kt"
click node_main_viewmodel "https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/ui/MainViewModel.kt"
click node_file_printer "https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/ui/FilePrinter.kt"
click node_driver_preferences "https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/data/DriverPreferences.kt"
click node_print_service "https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/service/PrintylanPrintService.kt"
click node_discovery_session "https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/service/UsbDiscoverySession.kt"
click node_usb_scanner "https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/usb/UsbPrinterScanner.kt"
click node_usb_permissions "https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/usb/UsbPermissions.kt"
click node_printer_probe "https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/usb/PrinterProbe.kt"
click node_usb_connection "https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/usb/UsbPrinterConnection.kt"
click node_android_mapping "https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/service/AndroidPrintMapping.kt"
click node_job_processor "https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/service/PrintJobProcessor.kt"
click node_pdf_renderer "https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/render/BandedPdfPage.kt"
click node_driver_selector "https://github.com/vermilion10/printylan/blob/main/core/driver/src/main/kotlin/com/printylan/driver/DriverSelector.kt"
click node_printer_driver "https://github.com/vermilion10/printylan/blob/main/core/driver/src/main/kotlin/com/printylan/driver/PrinterDriver.kt"
click node_pwg_driver "https://github.com/vermilion10/printylan/blob/main/core/driver/src/main/kotlin/com/printylan/driver/PwgRasterDriver.kt"
click node_pcl_driver "https://github.com/vermilion10/printylan/blob/main/core/driver/src/main/kotlin/com/printylan/driver/PclRasterDriver.kt"
click node_pdf_driver "https://github.com/vermilion10/printylan/blob/main/core/driver/src/main/kotlin/com/printylan/driver/PdfPassthroughDriver.kt"
click node_canon_driver "https://github.com/vermilion10/printylan/blob/main/core/driver/src/main/kotlin/com/printylan/driver/CanonIvecDriver.kt"
click node_domain_models "https://github.com/vermilion10/printylan/blob/main/core/model/src/main/kotlin/com/printylan/model/PrinterCapabilities.kt"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_main_activity,node_printers_screen,node_main_viewmodel,node_file_printer,node_driver_preferences,node_user toneBlue
class node_print_service,node_discovery_session,node_usb_scanner,node_usb_permissions,node_printer_probe,node_usb_connection,node_android_mapping toneAmber
class node_job_processor,node_pdf_renderer toneMint
class node_driver_selector,node_printer_driver,node_pwg_driver,node_pcl_driver,node_pdf_driver,node_canon_driver,node_domain_models toneRose
class node_android_print,node_usb_printer toneIndigo
```

## Components

### App interface

- [Main activity](https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/ui/MainActivity.kt): `app/src/main/kotlin/com/printylan/ui/MainActivity.kt`
- [Printers screen](https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/ui/PrintersScreen.kt): `app/src/main/kotlin/com/printylan/ui/PrintersScreen.kt`
- [Printer view model](https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/ui/MainViewModel.kt): `app/src/main/kotlin/com/printylan/ui/MainViewModel.kt`
- [File printing](https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/ui/FilePrinter.kt): `app/src/main/kotlin/com/printylan/ui/FilePrinter.kt`
- [Driver overrides](https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/data/DriverPreferences.kt): `app/src/main/kotlin/com/printylan/data/DriverPreferences.kt`

### Printer discovery

- [Print service](https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/service/PrintylanPrintService.kt): `app/src/main/kotlin/com/printylan/service/PrintylanPrintService.kt`
- [Printer discovery](https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/service/UsbDiscoverySession.kt): `app/src/main/kotlin/com/printylan/service/UsbDiscoverySession.kt`
- [USB scanner](https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/usb/UsbPrinterScanner.kt): `app/src/main/kotlin/com/printylan/usb/UsbPrinterScanner.kt`
- [USB permissions](https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/usb/UsbPermissions.kt): `app/src/main/kotlin/com/printylan/usb/UsbPermissions.kt`
- [Printer probe](https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/usb/PrinterProbe.kt): `app/src/main/kotlin/com/printylan/usb/PrinterProbe.kt`
- [USB connection](https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/usb/UsbPrinterConnection.kt): `app/src/main/kotlin/com/printylan/usb/UsbPrinterConnection.kt`
- [Print mapping](https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/service/AndroidPrintMapping.kt): `app/src/main/kotlin/com/printylan/service/AndroidPrintMapping.kt`

### Print jobs

- [Job processor](https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/service/PrintJobProcessor.kt): `app/src/main/kotlin/com/printylan/service/PrintJobProcessor.kt`
- [Banded PDF rendering](https://github.com/vermilion10/printylan/blob/main/app/src/main/kotlin/com/printylan/render/BandedPdfPage.kt): `app/src/main/kotlin/com/printylan/render/BandedPdfPage.kt`

### Drivers and formats

- [Driver selection](https://github.com/vermilion10/printylan/blob/main/core/driver/src/main/kotlin/com/printylan/driver/DriverSelector.kt): `core/driver/src/main/kotlin/com/printylan/driver/DriverSelector.kt`
- [Driver interface](https://github.com/vermilion10/printylan/blob/main/core/driver/src/main/kotlin/com/printylan/driver/PrinterDriver.kt): `core/driver/src/main/kotlin/com/printylan/driver/PrinterDriver.kt`
- [PWG Raster](https://github.com/vermilion10/printylan/blob/main/core/driver/src/main/kotlin/com/printylan/driver/PwgRasterDriver.kt): `core/driver/src/main/kotlin/com/printylan/driver/PwgRasterDriver.kt`
- [PCL raster](https://github.com/vermilion10/printylan/blob/main/core/driver/src/main/kotlin/com/printylan/driver/PclRasterDriver.kt): `core/driver/src/main/kotlin/com/printylan/driver/PclRasterDriver.kt`
- [PDF passthrough](https://github.com/vermilion10/printylan/blob/main/core/driver/src/main/kotlin/com/printylan/driver/PdfPassthroughDriver.kt): `core/driver/src/main/kotlin/com/printylan/driver/PdfPassthroughDriver.kt`
- [Canon IVEC](https://github.com/vermilion10/printylan/blob/main/core/driver/src/main/kotlin/com/printylan/driver/CanonIvecDriver.kt): `core/driver/src/main/kotlin/com/printylan/driver/CanonIvecDriver.kt`
- [Print domain types](https://github.com/vermilion10/printylan/blob/main/core/model/src/main/kotlin/com/printylan/model/PrinterCapabilities.kt): `core/model/src/main/kotlin/com/printylan/model/PrinterCapabilities.kt`

### Other components

- **User**
- **Android print framework**
- **USB printer**

## Connections

- User → Main activity: opens and selects
- Main activity → Printers screen: displays
- Printers screen → Printer view model: requests printer actions
- Main activity → File printing: starts file print
- Printer view model → Driver overrides: saves override
- Printer view model → USB scanner: refreshes printers
- Android print framework → Print service: binds and queues jobs
- Print service → Printer discovery: creates session
- Printer discovery → USB scanner: refreshes and observes
- Printer discovery → USB permissions: requests access
- Printer discovery → Printer probe: inspects printer
- Printer discovery → Print mapping: maps capabilities
- USB scanner → USB printer: detects attached device
- USB permissions → USB printer: requests device access
- Printer probe → USB connection: opens for probing
- USB connection → USB printer: reads ID and status
- Printer probe → Driver selection: selects language
- Printer probe → Driver overrides: checks override
- Print mapping → Print domain types: maps capabilities
- Print service → Job processor: queues or cancels
- Job processor → USB permissions: obtains printer access
- Job processor → Printer probe: gets printer driver
- Job processor → Banded PDF rendering: renders PDF bands
- Job processor → Driver interface: encodes rendered pages
- Driver selection → PWG Raster: selects by ID
- Driver selection → PCL raster: selects by ID
- Driver selection → PDF passthrough: selects by ID
- Driver selection → Canon IVEC: selects by ID
- PWG Raster → Driver interface: implements
- PCL raster → Driver interface: implements
- PDF passthrough → Driver interface: implements
- Canon IVEC → Driver interface: implements
- Job processor → USB connection: writes print stream
- USB connection → USB printer: sends print data
