File: printer_info_cups.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (129 lines) | stat: -rw-r--r-- 5,197 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// 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.

#include <algorithm>
#include <array>
#include <string>

#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/version.h"
#include "chrome/browser/ash/printing/printer_info.h"
#include "chromeos/printing/cups_printer_status.h"
#include "chromeos/printing/printer_configuration.h"
#include "printing/backend/cups_jobs.h"
#include "printing/printer_status.h"

namespace {

const char kPdfMimeType[] = "application/pdf";
const char kPwgRasterMimeType[] = "image/pwg-raster";

// Wraps several printing data structures so that we can use
// PostTaskAndReplyWithResult().
struct QueryResult {
  printing::PrinterQueryResult result;
  printing::PrinterInfo printer_info;
  printing::PrinterStatus printer_status;
};

// Returns true if any of the |ipp_versions| are greater than or equal to 2.0.
bool AllowedIpp(const std::vector<base::Version>& ipp_versions) {
  return std::ranges::any_of(ipp_versions, [](const base::Version& version) {
    return version.IsValid() && version.components()[0] >= 2;
  });
}

// Returns true if |mime_type| is one of the supported types.
bool SupportedMime(const std::string& mime_type) {
  return mime_type == kPwgRasterMimeType || mime_type == kPdfMimeType;
}

// Returns true if |formats| contains one of the supported printer description
// languages for an autoconf printer identified by MIME type.
bool SupportsRequiredPDLS(const std::vector<std::string>& formats) {
  return std::ranges::any_of(formats, &SupportedMime);
}

// Returns true if |info| describes a printer for which we want to attempt
// automatic configuration.
bool IsAutoconf(const ::printing::PrinterInfo& info) {
  return info.ipp_everywhere || (AllowedIpp(info.ipp_versions) &&
                                 SupportsRequiredPDLS(info.document_formats));
}

// Dispatches an IPP request to |host| to retrieve printer information.  Returns
// a nullptr if the request fails.
QueryResult QueryPrinterImpl(const std::string& host,
                             const int port,
                             const std::string& path,
                             bool encrypted) {
  QueryResult result;
  result.result =
      ::printing::GetPrinterInfo(host, port, path, encrypted,
                                 &result.printer_info, &result.printer_status);
  if (result.result != ::printing::PrinterQueryResult::kSuccess) {
    LOG(ERROR) << "Could not retrieve printer info from "
               << (encrypted ? "ipps://" : "ipp://") << host << ":" << port
               << path << ": " << static_cast<int>(result.result);
  }

  return result;
}

// Handles the request for |info|.  Parses make and model information before
// calling |callback|.
void OnPrinterQueried(ash::PrinterInfoCallback callback,
                      const QueryResult& query_result) {
  const ::printing::PrinterQueryResult& result = query_result.result;
  const ::printing::PrinterInfo& printer_info = query_result.printer_info;
  const ::printing::PrinterStatus& printer_status = query_result.printer_status;
  if (result != ::printing::PrinterQueryResult::kSuccess) {
    VLOG(1) << "Could not reach printer";
    std::move(callback).Run(result, ::printing::PrinterStatus(),
                            /*make_and_model=*/std::string(),
                            /*document_formats=*/{}, /*ipp_everywhere=*/false,
                            chromeos::PrinterAuthenticationInfo{},
                            chromeos::IppPrinterInfo{});
    return;
  }
  std::move(callback).Run(
      result, printer_status, printer_info.make_and_model,
      printer_info.document_formats, IsAutoconf(printer_info),
      {.oauth_server = printer_info.oauth_server,
       .oauth_scope = printer_info.oauth_scope},
      {/*document_formats=*/printer_info.document_formats,
       /*document_format_default=*/printer_info.document_format_default,
       /*document_format_preferred=*/printer_info.document_format_preferred,
       /*urf_supported=*/printer_info.urf_supported,
       /*pdf_versions=*/printer_info.pdf_versions,
       /*ipp_features=*/printer_info.ipp_features,
       /*mopria_certified=*/printer_info.mopria_certified,
       /*printer_kind=*/printer_info.printer_kind});
}

}  // namespace

namespace ash {

void QueryIppPrinter(const std::string& host,
                     const int port,
                     const std::string& path,
                     bool encrypted,
                     PrinterInfoCallback callback) {
  DCHECK(!host.empty());

  // QueryPrinterImpl could block on a network call for a noticable amount of
  // time (100s of ms). Also the user is waiting on this result.  Thus, run at
  // USER_VISIBLE with MayBlock.
  base::ThreadPool::PostTaskAndReplyWithResult(
      FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()},
      base::BindOnce(&QueryPrinterImpl, host, port, path, encrypted),
      base::BindOnce(&OnPrinterQueried, std::move(callback)));
}

}  // namespace ash