File: ipp_client_info_calculator.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 (148 lines) | stat: -rw-r--r-- 6,112 bytes parent folder | download | duplicates (6)
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ash/printing/ipp_client_info_calculator.h"

#include <cstdint>
#include <memory>
#include <string_view>

#include "base/check.h"
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/system/sys_info.h"
#include "chrome/browser/ash/policy/core/device_attributes.h"
#include "chrome/browser/ash/policy/core/device_attributes_impl.h"
#include "chromeos/ash/components/settings/cros_settings.h"
#include "chromeos/ash/components/settings/cros_settings_names.h"
#include "components/version_info/version_info.h"
#include "printing/mojom/print.mojom.h"

namespace ash::printing {

namespace {

using ::printing::mojom::IppClientInfo;
using ::printing::mojom::IppClientInfoPtr;

constexpr char kOsInfoClientName[] = "ChromeOS";
constexpr char kDeviceDirectoryApiIdPlaceholder[] =
    "${DEVICE_DIRECTORY_API_ID}";
constexpr char kDeviceSerialNumberPlaceholder[] = "${DEVICE_SERIAL_NUMBER}";
constexpr char kDeviceAssetIdPlaceholder[] = "${DEVICE_ASSET_ID}";
constexpr char kDeviceAnnotatedLocationPlaceholder[] =
    "${DEVICE_ANNOTATED_LOCATION}";

// Replace device variables found in `str` with the provided values.
std::string ReplaceDeviceVariables(std::string template_with_vars,
                                   std::string_view api_id,
                                   std::string_view serial,
                                   std::string_view asset_id,
                                   std::string_view location) {
  base::ReplaceSubstringsAfterOffset(&template_with_vars, 0,
                                     kDeviceDirectoryApiIdPlaceholder, api_id);
  base::ReplaceSubstringsAfterOffset(&template_with_vars, 0,
                                     kDeviceSerialNumberPlaceholder, serial);
  base::ReplaceSubstringsAfterOffset(&template_with_vars, 0,
                                     kDeviceAssetIdPlaceholder, asset_id);
  base::ReplaceSubstringsAfterOffset(
      &template_with_vars, 0, kDeviceAnnotatedLocationPlaceholder, location);
  return template_with_vars;
}

class IppClientInfoCalculatorImpl : public IppClientInfoCalculator {
 public:
  IppClientInfoCalculatorImpl(
      std::unique_ptr<policy::DeviceAttributes> device_attributes,
      const std::string& chrome_milestone)
      : cros_settings_(CrosSettings::Get()),
        device_attributes_(std::move(device_attributes)) {
    // Calculate the initial client-info values. The admin-configured
    // `client-info` value with device information can change later if the
    // `kDevicePrintingClientNameTemplate` setting changes.
    CalculateClientInfoWithDeviceValues();
    CalculateClientInfoWithOSVersion(chrome_milestone);

    // Recalculate `client-info` with device information when
    // `kDevicePrintingClientNameTemplate` setting changes.
    // base::Unretained(this) is safe here because the subscription is scoped to
    // the lifetime of `this` already.
    auto callback = base::BindRepeating(
        &IppClientInfoCalculatorImpl::CalculateClientInfoWithDeviceValues,
        base::Unretained(this));
    client_name_template_subscription_ =
        CrosSettings::Get()->AddSettingsObserver(
            kDevicePrintingClientNameTemplate, std::move(callback));
  }

 private:
  IppClientInfoPtr GetOsInfo() const override {
    DCHECK(os_info_);
    return os_info_.Clone();
  }

  IppClientInfoPtr GetDeviceInfo() const override {
    return device_info_.Clone();
  }

  void CalculateClientInfoWithDeviceValues() {
    std::string client_name_template = GetClientNameTemplateFromCrosSettings();
    if (client_name_template.empty()) {
      return;
    }
    std::string serial = device_attributes_->GetDeviceSerialNumber();
    std::string asset_id = device_attributes_->GetDeviceAssetID();
    std::string location = device_attributes_->GetDeviceAnnotatedLocation();
    std::string directory_api_id = device_attributes_->GetDirectoryApiID();
    std::string client_name =
        ReplaceDeviceVariables(std::move(client_name_template),
                               directory_api_id, serial, asset_id, location);
    device_info_ = IppClientInfo::New(IppClientInfo::ClientType::kOther,
                                      std::move(client_name),
                                      /*client_patches=*/std::nullopt,
                                      /*client_string_version=*/std::string(),
                                      /*client_version=*/std::nullopt);
  }

  void CalculateClientInfoWithOSVersion(const std::string& chrome_milestone) {
    DCHECK(base::SysInfo::IsRunningOnChromeOS());
    os_info_ = IppClientInfo::New(
        IppClientInfo::ClientType::kOperatingSystem, kOsInfoClientName,
        base::SysInfo::OperatingSystemVersion(), chrome_milestone,
        /*client_version=*/std::nullopt);
  }

  std::string GetClientNameTemplateFromCrosSettings() {
    std::string client_name_template;
    cros_settings_->GetString(kDevicePrintingClientNameTemplate,
                              &client_name_template);
    return client_name_template;
  }

  raw_ptr<const CrosSettings> cros_settings_;
  std::unique_ptr<policy::DeviceAttributes> device_attributes_;
  IppClientInfoPtr device_info_;
  IppClientInfoPtr os_info_;
  base::CallbackListSubscription client_name_template_subscription_;
};

}  // namespace

std::unique_ptr<IppClientInfoCalculator> IppClientInfoCalculator::Create() {
  return std::make_unique<IppClientInfoCalculatorImpl>(
      std::make_unique<policy::DeviceAttributesImpl>(),
      version_info::GetMajorVersionNumber());
}

std::unique_ptr<IppClientInfoCalculator>
IppClientInfoCalculator::CreateForTesting(
    std::unique_ptr<policy::DeviceAttributes> device_attributes,
    const std::string& chrome_milestone) {
  return std::make_unique<IppClientInfoCalculatorImpl>(
      std::move(device_attributes), chrome_milestone);
}

}  // namespace ash::printing