File: in_progress_jobs_storage_chromeos.cc

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (138 lines) | stat: -rw-r--r-- 5,578 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
130
131
132
133
134
135
136
137
138
// Copyright 2023 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/printing/web_api/in_progress_jobs_storage_chromeos.h"

#include "base/check_deref.h"
#include "base/containers/fixed_flat_map.h"
#include "base/containers/fixed_flat_set.h"
#include "base/containers/map_util.h"
#include "chrome/browser/printing/local_printer_utils_chromeos.h"

namespace printing {

namespace {

using PrintJobStatus = crosapi::mojom::PrintJobStatus;
using WebPrintJobState = blink::mojom::WebPrintJobState;

// Accepted job states. The ones not listed here are silently discarded.
static constexpr auto kJobStatusToJobStateMapping =
    base::MakeFixedFlatMap<PrintJobStatus, WebPrintJobState>({
        // clang-format off
        {PrintJobStatus::kStarted,   WebPrintJobState::kProcessing},
        {PrintJobStatus::kDone,      WebPrintJobState::kCompleted},
        {PrintJobStatus::kCancelled, WebPrintJobState::kCanceled},
        {PrintJobStatus::kError,     WebPrintJobState::kAborted},
        // clang-format on
    });

// Terminal states. Once the job reaches one of these, it will no longer be
// tracked (and hence removed from the storage).
static constexpr auto kTerminalJobStates =
    base::MakeFixedFlatSet<WebPrintJobState>({
        // clang-format off
        WebPrintJobState::kCompleted,
        WebPrintJobState::kCanceled,
        WebPrintJobState::kAborted,
        // clang-format on
    });

}  // namespace

InProgressJobsStorageChromeOS::InProgressJobsStorageChromeOS() {
  GetLocalPrinterInterface()->AddPrintJobObserver(
      observer_.BindNewPipeAndPassRemote(),
      crosapi::mojom::PrintJobSource::kIsolatedWebApp, base::DoNothing());

  // Disconnects might happen if the corresponding frame is going away or the
  // renderer process crashes.
  state_observers_.set_disconnect_handler(base::BindRepeating(
      &InProgressJobsStorageChromeOS::OnStateObserverDisconnected,
      base::Unretained(this)));
}

InProgressJobsStorageChromeOS::~InProgressJobsStorageChromeOS() = default;

void InProgressJobsStorageChromeOS::Cancel() {
  const auto& [printer_id, job_id] = controllers_.current_context();
  GetLocalPrinterInterface()->CancelPrintJob(printer_id, job_id,
                                             base::DoNothing());
}

void InProgressJobsStorageChromeOS::OnPrintJobUpdateDeprecated(
    const std::string& printer_id,
    uint32_t job_id,
    crosapi::mojom::PrintJobStatus status) {
  NOTREACHED();
}

void InProgressJobsStorageChromeOS::OnPrintJobUpdate(
    const std::string& printer_id,
    uint32_t job_id,
    crosapi::mojom::PrintJobUpdatePtr update) {
  auto id_pair_itr =
      job_id_to_observer_controller_id_pair_.find({printer_id, job_id});
  if (id_pair_itr == job_id_to_observer_controller_id_pair_.end()) {
    // This job doesn't belong to us or has already been discarded.
    return;
  }

  // See invariant description in the header.
  const auto& [observer_id, controller_id] = id_pair_itr->second;
  auto& observer = CHECK_DEREF(state_observers_.Get(observer_id));

  // Updates are forwarded to the renderer if either the `state` can be mapped
  // directly or printing is in progress (indicated by `pages_printed` > 0).
  // Cases are possible where the received `state` is unmapped; then it's
  // assumed to be `kProcessing` due to `pages_printed` being greater than zero.
  // Lastly, the notification might end up being equal to the existing job
  // configuration both in terms of `state` and `pages_printed`; in this case it
  // will be silently discarded by the renderer.
  auto* state = base::FindOrNull(kJobStatusToJobStateMapping, update->status);
  if (state || update->pages_printed > 0) {
    auto out_update = blink::mojom::WebPrintJobUpdate::New();
    out_update->state =
        state ? *state : blink::mojom::WebPrintJobState::kProcessing;
    if (update->pages_printed > 0) {
      out_update->pages_printed = update->pages_printed;
    }
    observer.OnWebPrintJobUpdate(std::move(out_update));
  }
  if (state && base::Contains(kTerminalJobStates, *state)) {
    state_observers_.Remove(observer_id);
    controllers_.Remove(controller_id);
    job_id_to_observer_controller_id_pair_.erase(id_pair_itr);
  }
}

void InProgressJobsStorageChromeOS::PrintJobAcknowledgedByThePrintSystem(
    const std::string& printer_id,
    uint32_t job_id,
    mojo::PendingRemote<blink::mojom::WebPrintJobStateObserver> observer,
    mojo::PendingReceiver<blink::mojom::WebPrintJobController> controller) {
  PrintJobUniqueId composite_id(printer_id, job_id);
  auto controller_id =
      controllers_.Add(this, std::move(controller), composite_id);
  auto observer_id = state_observers_.Add(std::move(observer));
  job_id_to_observer_controller_id_pair_[composite_id] =
      ObserverControllerIdPair(observer_id, controller_id);

  auto update = blink::mojom::WebPrintJobUpdate::New();
  update->state = blink::mojom::WebPrintJobState::kPending;
  CHECK_DEREF(state_observers_.Get(observer_id))
      .OnWebPrintJobUpdate(std::move(update));
}

void InProgressJobsStorageChromeOS::OnStateObserverDisconnected(
    mojo::RemoteSetElementId observer_id_in) {
  // By the time we get here `observer_id_in` will have already been removed
  // from `state_observers_`.
  base::EraseIf(job_id_to_observer_controller_id_pair_, [&](const auto& entry) {
    const auto& [observer_id, controller_id] = entry.second;
    return observer_id_in == observer_id;
  });
}

}  // namespace printing